Fix Clash Meta Sniffer HTTPS Errors: Skip Cert Verify and Exclude Domains
Enabling Sniffer in Clash Meta (Mihomo) is one of the most useful advanced moves you can make—it reads the SNI field from TLS ClientHello packets so domain-based routing works even when the kernel only sees a raw IP address. But a handful of sites, banking apps, or certificate-pinned services can start throwing HTTPS certificate errors or silently refusing connections right after you flip that switch. Before reaching for the nuclear option of skip-cert-verify or disabling Sniffer entirely, there is a well-ordered debugging path: verify the cause, add skip-domain exclusions for known problem domains, align fake-ip and override-destination settings, and only then consider whether cert verification on the proxy egress is actually the right knob to turn. This guide walks through every step.
What Sniffer actually does—and doesn't do
In redir-host mode or many TUN scenarios, connections arrive at the Clash kernel with a destination IP and no hostname. If your rule set is built around DOMAIN and DOMAIN-SUFFIX entries, those rules simply cannot fire without a hostname to match against. Sniffer solves this by peeking at the TLS handshake early enough to extract the Server Name Indication field, giving the rule engine the domain it needs before the connection is fully established.
Importantly, standard Sniffer does not decrypt or intercept application-layer HTTPS content. It reads handshake metadata only. This distinction matters when you start debugging: if the browser is showing "certificate does not match domain" or "certificate chain invalid," you need to separate side effects of how Sniffer rewrites connection metadata from completely unrelated causes like an expired node certificate, incorrect system clock, or corporate security software performing its own HTTPS inspection.
Mental model
Think of Sniffer as a labeling module that staples a hostname onto each connection so routing decisions stay accurate. Better labels mean more precise domain rules. But when a label interacts unexpectedly with override-destination, DNS mapping, or an app's own certificate pinning logic, a small exclusion list beats turning the whole feature off.
How to tell whether the problem is Sniffer-related
Before changing any configuration, do a quick A/B test: same node, same ruleset, toggle only sniffer.enable (or the equivalent GUI toggle). These patterns suggest a Sniffer interaction rather than a node or DNS issue:
- Only specific domains fail. Other sites work fine. The broken ones recover immediately when Sniffer is off.
- Banking, government, or enterprise VPN apps fail to connect or log in under proxy, and the kernel log shows TLS-related failures or repeated retries for those destinations.
- Policy routing shifts unexpectedly with fake-ip. A domain that should go direct starts hitting a proxy group (or the reverse), with occasional certificate warnings as a side effect.
- Failures multiply right after enabling
override-destination: true. That flag rewrites the connection target using sniffed data, amplifying any mismatch between what the app expects and what the kernel delivers.
If problems persist with Sniffer disabled, shift your focus to the DNS layer. Check dns.enhanced-mode, your nameserver and fallback configuration, and whether the system or browser has its own DNS-over-HTTPS resolver that bypasses the Clash kernel entirely. The DNS and fake-ip troubleshooting guide covers that path in detail.
Step one: add skip-domain exclusions
The most maintainable fix is rarely "disable Sniffer globally." Instead, add the handful of known-incompatible domains to the sniff exclusion list so their connections bypass the TLS sniffing logic entirely. Different GUI clients surface this as "skip sniffing domains," "sniffer exclusions," or similar—but under the hood they all map to the skip-domain key in the Mihomo sniffer block.
Exclusion entries commonly support suffix-wildcard syntax such as +.example.com to cover all subdomains. The exact wildcard rules vary by Mihomo version, so cross-check with the release notes for your build. Below is an illustrative structure—adjust indentation and merge points to match your existing config:
# Illustrative sniffer block — align with your Mihomo version docs
sniffer:
enable: true
sniff:
TLS:
ports: [443]
QUIC:
ports: [443]
skip-domain:
- '+.bank.example'
- '+.internal.corp'
force-dns-mapping: true
parse-pure-ip: false
override-destination: false
A practical tip: resist the temptation to paste a 200-entry community list all at once. Find the precise hostname in the connection log first, add one to three entries, reload the config, then retest. Once things are stable, decide whether to merge your exclusions with the defaults that subscription templates may already carry.
How to find the right domains to add
- Filter failed requests in the Clash connection log; look for the SNI or the host field in the URL.
- Open browser DevTools → Network tab, find the failing main-document request, and note its exact domain name.
- For in-app web views, record API subdomains rather than just the top-level marketing domain—those are usually what matters.
override-destination and fake-ip interactions
Setting override-destination: true tells the kernel to use the sniffed hostname to rewrite the connection's destination. This helps in complex CDN or multi-certificate setups where the kernel would otherwise route purely by IP, but it also raises the chance of a mismatch: the client believes it is connecting to one IP or certificate SAN, while the rewritten path takes it elsewhere. If you turned this on recently and failures spiked, revert it to false first, confirm the baseline recovers, then decide case-by-case whether individual policy groups need more granular domain rules instead.
fake-ip and Sniffer are both mechanisms to keep domain-level rules useful, but they operate at different stages. When combined carelessly, the DNS resolution phase and the connection phase can disagree about which domain is actually being accessed. The safest debugging strategy—consistent with the advice in the DNS troubleshooting companion—is to change one variable at a time: pin your DNS mode and nameservers first, then experiment with Sniffer; or lock Sniffer off to validate DNS, then re-enable Sniffer and add exclusions.
| Setting | Common benefit | Common risk |
|---|---|---|
sniffer.enable |
Fills in hostname for IP-only connections; improves domain rule accuracy | Rare sites or apps incompatible with sniff metadata |
override-destination |
Corrects routing that would otherwise follow only IP | Can conflict with apps' certificate validation expectations |
fake-ip |
Earlier rule matching, snappier response feel | Needs alignment with Sniffer and redir stack to avoid phase mismatch |
When skip-cert-verify is and isn't the answer
The Clash community frequently treats skip-cert-verify as a catch-all cure for certificate problems, but understanding what it actually toggles is essential. This option controls TLS verification for the connection between Clash and your proxy node (your subscription server or self-hosted entry point). It has nothing to do with the certificate your browser sees for the destination website.
Setting skip-cert-verify: true on a proxy entry tells the Clash client to stop validating the node's own certificate. That meaningfully raises the risk of connecting to a forged or hijacked entry point without any warning—it is appropriate only as a short-lived diagnostic tool or in a tightly controlled private environment where you are certain of the endpoint's identity.
The healthier sequence when you suspect node TLS issues is: switch to a node whose certificate chain is complete and trusted; check that your local system clock is accurate; confirm that no corporate security software is intercepting and re-signing your TLS; and only then, on a single proxy entry, briefly enable skip-cert-verify: true to confirm your hypothesis. Remove it or fix the root cause once confirmed—never spread it across your entire template.
Security note
skip-cert-verify does not make the destination website trusted. It only skips verification on the Clash-to-proxy-node leg. The browser still validates the website's certificate independently. If the browser still flags a certificate error, look at the site itself, your system root certificate store, or whether an HTTP interception tool is in the path.
Working with GUI clients versus raw YAML
Clash Verge Rev, OpenClash, and other front-ends expose Sniffer controls at different depths. Some offer a single toggle plus a TLS/QUIC port list and an exclusion field; others require editing the underlying YAML directly. Whichever path you use, maintain a single source of truth: avoid defining sniffer blocks in both a "config override" section and a subscription merge snippet simultaneously—one will silently overwrite the other in an order that may surprise you.
If you are new to TUN mode or the Mihomo core, complete the baseline setup first. For Windows, the Clash for Windows installation guide covers subscription import and mode switching. On macOS, driver permissions and Network Extensions matter before any advanced tuning—see the Clash Verge Rev macOS article. Trying to layer Sniffer configuration onto a broken baseline often causes driver or permission problems to masquerade as sniffing problems.
QUIC and HTTP/3 sniffing notes
Mihomo can also sniff QUIC (HTTP/3) traffic on UDP 443. If you configured QUIC sniffing but only certain sites fail, test with just TLS sniffing enabled first to isolate the variable. Some network environments rate-limit or block UDP 443 outright; the resulting failure looks superficially like a TLS handshake or certificate error but is actually the QUIC connection never completing. A quick test is to disable QUIC sniffing temporarily (or force the affected site to fall back to TCP via browser flags) and see whether the problem disappears.
# To isolate QUIC issues, sniff only TLS first
sniffer:
enable: true
sniff:
TLS:
ports: [443]
# QUIC temporarily commented out for diagnosis
# QUIC:
# ports: [443]
skip-domain:
- '+.problematic-site.example'
FAQ
Almost every HTTPS site breaks when I enable Sniffer
This usually points to a global network issue, incorrect system time, or node TLS problems—not Sniffer itself. Disable Sniffer as a baseline test; if everything is still broken, check node availability and ports, confirm your clock is within a minute of real time, and look for local security software doing HTTPS scanning.
Only one app fails; the browser is fine
High likelihood of certificate pinning or a custom TLS validation library inside the app. Add the app's relevant domains to skip-domain, or if your rule set supports it, route that app's traffic DIRECT to bypass the sniffing stack entirely.
Banking or government sites refuse to connect
These often combine certificate pinning with strict TLS requirements. Try skip-domain for the specific hostnames first. If failures persist, check whether override-destination is on; revert it and retest. Avoid skip-cert-verify in this scenario—it won't help with the site's own certificate and may expose your proxy tunnel to interception.
Turning off override-destination broke something else
Some routing setups genuinely rely on destination rewriting for accuracy—typically in scenarios where IP-based rules are absent and the sniffed hostname is the only reliable routing key. If reverting override-destination fixes the certificate issue but breaks other routing, add targeted skip-domain entries for the certificate-failing hosts instead of leaving the flag off globally.
Step-by-step debugging checklist
- Record the exact hostname(s) that fail and capture the error message or screenshot plus kernel log lines.
- A/B test by toggling only Sniffer; confirm whether the error disappears with it off.
- If Sniffer is the cause, add the failing hostname(s) to
skip-domainand reload—test incrementally, one to three entries at a time. - If
override-destinationistrue, revert tofalseand retest before adding more exclusions. - Check fake-ip and DNS mode for phase mismatches; refer to the DNS guide if needed.
- Only after ruling out all the above: enable
skip-cert-verify: trueon the specific proxy entry temporarily to check whether the proxy node's own cert is to blame. Remove it once confirmed or switch to a node with a valid certificate.
Keeping exclusion lists maintainable
Sniffer is one of the more powerful features in Mihomo cores: it meaningfully improves domain routing accuracy in scenarios where DNS alone cannot supply a reliable hostname. The trade-off is a small ongoing maintenance burden when apps or sites change their TLS behavior.
Treat your skip-domain list the same way you would treat firewall exceptions: keep entries specific, annotate why each one is there (a brief comment next to the entry is enough), and review the list when you upgrade the core or change your subscription. A well-tended exclusion list of five entries is far more reliable than a disabled Sniffer or a global skip-cert-verify that papers over the real problem.
Pair Sniffer configuration with a clear DNS strategy—enhanced-mode, trusted nameservers, and a consistent fake-ip or redir-host decision. When those three pieces are aligned, Sniffer rarely causes surprises outside the handful of sites that genuinely need exclusions.
Advanced feature, layered fix
Sniffer makes TLS domain routing more accurate. When HTTPS errors appear, prioritize domain exclusions and DNS alignment over cert-verify shortcuts.
Download Clash