Why “Proxy On” Still Routes Some Sites Wrong

If you have used Clash-family clients for a while, you have probably seen this pattern: most browsing obeys your YAML, yet a handful of hosts stubbornly land in the wrong strategy group or follow a blunt GEOIP bucket you never intended. One frequent cause is deceptively simple: the core never learned the domain name for that connection early enough. Browsers that speak HTTP/3 often move bulk transfers to QUIC on UDP/443. Classic TLS on TCP at least exposes a cleartext ClientHello with SNI most of the time, but your stack still has to parse it and feed the result into the matcher. When the dataplane only sees an IP tuple, or QUIC needs protocol-aware parsing before a domain surfaces, domain-based rules lose their grip and you fall through to IP rules or region defaults.

Clash Meta (the open mihomo core and the ecosystem of GUIs built on it) addresses this with a first-party feature usually called the Sniffer: a traffic inspection stage that extracts hostnames from eligible flows and makes them visible to the rule engine without turning your router into a sketchy “SSL bump” appliance. The goal is pragmatic — better split routing — not decrypting payloads. This guide shows how to enable Sniffer responsibly, how it interacts with TUN mode and DNS, and how to verify that your QUIC and SNI paths finally hit the same thoughtful policy you already wrote for TCP.

Prerequisites: Meta Core, TUN, and Realistic Expectations

Sniffer is not a legacy Premium core toggle. Confirm your client actually runs a maintained mihomo / Clash Meta branch; the YAML keys and defaults evolve, and copying a random gist from three years ago is a recipe for silent no-ops. Next, accept an operational truth: Sniffer complements capture. If your traffic never traverses the core’s pipeline — for example because you are still on plain system proxy and an app ignores it — there is nothing to sniff. For QUIC and many games, TUN transparent mode is usually the dependable prerequisite so UDP and non-proxy-aware sockets actually reach Clash. Our TUN mode guide covers stacks, dns-hijack, and permissions; read it once, enable TUN sanely, then return here for Sniffer specifics.

Finally, adjust expectations about privacy and fingerprinting. Sniffer reads metadata that was already on the wire in cleartext handshake shapes — it is not magic decryption. Some protocols obscure names (certain QUIC privacy features, ESNI/ECH deployments, niche tunnels). In those cases Sniffer cannot invent a domain that never appeared; your fallback remains sound IP-CIDR rules, provider tags, or conservative DIRECT splits. Treat Sniffer as a best-effort signal booster for routing, not a guarantee for every hostile or ultra-privacy endpoint.

Minimal Sniffer YAML You Can Paste and Iterate

Start with a small, explicit block so upgrades behave predictably. The following pattern is representative of current mihomo-family configs: enable the master switch, declare which protocols to sniff, pin sensible ports, and opt into the behaviors that help domain rules see traffic that would otherwise remain “raw IP.” Always reconcile with the sample your GUI emits — some clients wrap these fields in a profile editor, but the underlying YAML remains the contract.

# Sniffer (mihomo / Clash Meta family) — illustrative baseline
sniffer:
  enable: true
  sniff:
    TLS:
      ports: [443, 8443]
    QUIC:
      ports: [443]
  force-dns-mapping: true
  parse-pure-ip: true
  override-destination: true

sniff.TLS focuses the parser on typical HTTPS-style TCP ports where a ClientHello with SNI is expected. sniff.QUIC does the analogous work for UDP transports that carry HTTP/3; without this, QUIC may remain an anonymous datagram flow until it is too late for your DOMAIN-SUFFIX lines to matter. force-dns-mapping and parse-pure-ip help stitch together clues when applications pinned an IP literal or your DNS layer answered in a way that obscures the original name. They are not “free complexity” — if misaligned with a contrived DNS scheme, they can make debugging harder — so flip them on, test, and keep a one-command rollback in version control.

override-destination is the philosophical fork in the road. When true, the core may rewrite the destination identity used during matching so that subsequent rule passes “see” the sniffed hostname instead of only the raw IP. That dramatically improves split routing for TLS and QUIC, but it also means you must trust the sniffed name and understand that policy is now operating on reconstructed metadata. If you observe odd loops or unexpected upstream selection, temporarily set override-destination: false to bisect whether rewriting amplifies the issue; pair that test with concise logging and a controlled reproduction site rather than thrashing ten unrelated toggles.

QUIC (HTTP/3) vs TLS SNI: What Sniffer Actually Fixes

TLS on TCP still drives a huge share of the web. For most exits, the first packets after the TCP handshake expose enough structure for a stateful parser to recover SNI quickly. Sniffer plugs that hostname into the same conceptual slot your DNS module would have used, which lets DOMAIN, DOMAIN-SUFFIX, and GEOSITE-style matches fire in the right order. Without Sniffer, a connection that began as an IP literal might never touch those lines, so you “mysteriously” inherit the MATCH rule at the bottom — often a region or catch-all proxy you did not mean for that service.

QUIC flips the performance story: zero-RTT resumption, connection migration, and UDP pacing make HTTP/3 lovely for users, but the dataplane is no longer “TCP with a cute header.” Browsers negotiate HTTP/3 eagerly on major properties, which means you can appear “on proxy” for TCP assets while bulk data silently rides QUIC beside it. If your stack ignored QUIC sniffing, you would blame the wrong node or conclude your rules “do not work on site X,” when in reality the UDP side never matched your domain clauses. Enabling sniff.QUIC closes that gap in one disciplined motion — provided TUN (or an equivalent capture path) actually delivers those UDP datagrams to userspace in the first place.

When debugging a single stubborn site, temporarily disable HTTP/3 in your browser (or use a QUIC-less profile) as a bisection step. If behavior snaps back to your YAML expectations, you have strong evidence that QUIC pathing — not DNS or certificate trust — was the variable.

DNS, Fake-IP, and Sniffer: Keep One Story, Not Three

Sniffer is not a substitute for coherent DNS. If your resolver answers outside Clash, or fake-ip filters omit critical CDN names, you can still paint yourself into a corner where the IP seen on the wire disagrees with the name you think you are visiting. A robust setup usually combines three cooperating layers: TUN + DNS hijack so queries enter the core, fake-ip or redir-host semantics chosen deliberately, and Sniffer as the backstop when applications short-circuit DNS or pin addresses anyway. Re-read the DNS sections in our TUN guide any time you enable Sniffer alongside a new subscription template — template authors love to paste dramatic fake-ip-filter lists that “fix Netflix” while silently breaking the corporate SSO you need tomorrow.

When testing, pick observables: log lines that print the resolved policy route, dashboard columns that show hostnames rather than only endpoints, and a repeatable URL that triggers QUIC (many large video and search properties do so by default). Change one axis at a time — DNS mode, Sniffer on/off, override-destination — or you will chase phantoms.

Split Rules Still Win or Lose on Order

Sniffer does not absolve you from rule hygiene. If your GEOIP,CN or a broad proxy group sits above site-specific lines, better metadata simply steers into the wrong bucket faster. Audit from top to bottom: LAN and RFC1918 DIRECT, critical intranet suffixes, vendor-specific DOMAIN sets, then regional defaults. For a methodology refresher on matchers and strategy groups, see our deep dive on Clash rule-based splitting; Sniffer only improves the inputs to that engine.

Pay attention to transport-aware outbounds. A QUIC flow matched “correctly” to a policy is still useless if the selected node speaks only TCP HTTP proxy. When you design groups for sensitive sites, verify that the underlying profile supports the protocols you expect, or explicitly pin HTTP/3-heavy domains to exits that handle UDP responsibly. This overlaps with gaming advice — our UDP gaming and voice article walks through similar dataplane pitfalls, even though the user story differs.

How to Verify Sniffer Is Doing Something Useful

Start with coarse signals: enable Sniffer, reload the running config, and load a target property twice — once with HTTP/3 forced off, once with defaults. Watch whether the dashboard’s connection rows begin showing meaningful hostnames for flows that used to appear as bare IPs. If your client surfaces “process name” or “rule chain” columns, confirm the QUIC rows reference the domain you expect before the final outbound locks in.

Then escalate to intentional stress tests: multiple CDNs, a site known to downgrade to TCP when QUIC fails, and a local DIRECT exception you control. You are looking for consistent policy selection, not vanity metrics. If results flicker only during url-test group flaps, stabilize the group — Sniffer cannot compensate for an outbound that changes every few seconds.

Troubleshooting When Sniffer Is On but Routing Feels Random

Symptom: Logs Still Show Only IPs for HTTPS

Confirm TUN is actually capturing the relevant interface and that you did not leave a conflicting VPN below or above Clash in the stack. Double-check that the flow is really TLS on the ports you sniff — exotic ports need explicit entries. For local MITM tooling or corporate inspection proxies, handshake shapes may differ; temporarily bypass those layers to see if parsing recovers.

Symptom: QUIC Stays on the Wrong Exit

Ensure QUIC appears under sniff with the correct ports, and that your node forwards UDP. If an intermediate relay strips QUIC, browsers may race TCP and UDP unpredictably. As a mitigation, some operators pin certain domains to TCP-friendly exits; document that as an explicit policy rather than hoping Sniffer will fix a broken UDP path.

Symptom: Loops or Timeouts After Enabling override-destination

Roll back override-destination first. Inspect for circular references where a sniffed name resolves back through a resolver that itself depends on the tunnel you are building. This is the same class of DNS loop pain TUN users know; Sniffer just surfaces it on QUIC-heavy sites sooner because more parallel connections start at once.

Security and Policy Notes (Short and Practical)

Sniffer increases visibility into handshake metadata for traffic your core already terminates in policy. It is not a license to ignore local law, workplace acceptable-use policies, or vendor terms. If you administer machines for family or colleagues, disclose that connection metadata is parsed for routing — most people care far less than they do about full HTTPS MITM, but transparency still matters. Rotate configs through git or signed profiles so you can audit what changed when a teammate “just tweaked Sniffer for TikTok.”

Where to Go Next in the Clash Docs

Sniffer sits at the intersection of capture, DNS, and rules. The project’s documentation hub remains the authoritative map for feature concepts; use this article as a task-focused supplement when your symptom language is “HTTP/3” or “SNI not matching.” If you are also tuning dashboards or REST access, pair this guide with our notes on locking down external-controller and Secret so convenience features do not become accidental remote admin holes.

Closing: Make Advanced Routing Boring Again

QUIC and modern TLS are not “edge cases” anymore — they are the default path for performance-hungry sites. Clash Meta’s Sniffer exists so your carefully written split routes remain honest when the transport stops looking like textbook TCP. Combined with disciplined TUN setup, DNS that tells one consistent story, and rules ordered like a table of contents rather than a junk drawer, Sniffer turns “why is only this app weird?” into a solvable checklist instead of a mystic art.

Compared with constantly swapping mystery profiles, a maintained mihomo-based client that exposes Sniffer, TUN, and logging in plain language keeps you grounded when platforms move fast and your deadlines do not wait. That operational calm is the real premium feature — not any single protocol trick.

→ Download Clash for free and experience the difference on Windows, macOS, Android, iOS, or Linux — wire up TUN, enable Sniffer thoughtfully, and iterate until QUIC and SNI flows land where your policy says they should.