“Connected” only proves part of the story
In most Clash-family clients, the green badge is answering a narrow question: did the local controller start, and can it talk to the upstream core? It is not a promise that every browser tab, Electron app, or background updater suddenly learned how to route through your policy stack. Many “no internet” tickets are really three different layers tangled into one complaint: the GUI status, the DNS pipeline, and the final outbound path chosen by rules.
That is why the fastest fix is rarely “toggle TUN again” or “download a mega rule list.” The fastest fix is evidence: one failing hostname, one timestamped log burst, and one clear question—did we die before DNS, after DNS but on the wrong policy, or on the tunnel itself?
If you have never written routing YAML before, skim the beginner routing guide on this blog so the vocabulary below (policy groups, MATCH, DIRECT) lands in context. You do not need to be fluent on day one; you only need enough literacy to read what the log already told you.
Step zero: reproduce like a technician, not like a reviewer
Pick one concrete target first. A plain https://example.com is fine if it fails consistently; a JSON API you rely on is even better because it removes “maybe the site is down” noise. Turn off parallel experiments: do not simultaneously change DNS mode, swap rule providers, and reinstall drivers. Science works when you change one variable at a time.
Open your client’s connection table if it has one, or the core log view if that is what your build exposes. Trigger the failure once, then freeze the screen long enough to copy the line that mentions your hostname or its resolved IP. If you cannot find any line at all, you are often dealing with traffic that never entered the proxy path—which pushes you toward system proxy settings, per-app bypass lists, or TUN coverage rather than subscription quality.
On macOS, terminals frequently ignore the GUI proxy; if your symptom is “Safari works, curl does not,” start from the macOS terminal proxy guide instead of burning an evening tuning nodes you never reached.
Step one: read the log like a decision tree
Exact wording varies between Mihomo builds and GUI wrappers, but the shape of failures is stable. Learn to classify messages into four buckets: DNS, routing choice, TLS or certificate, and dial or transport. Once you know the bucket, the fix stops being superstition.
DNS-shaped pain often shows up as repeated lookup timeouts, NXDOMAIN surprises, or “could not resolve” style errors that appear before you see a meaningful outbound group. If the log never prints a resolved address yet the browser already gave up, suspect nameserver reachability, fake-ip misalignment, or a captive portal intercepting UDP/53. When in doubt, compare what Clash logged against what a plain dig returns on the same machine while the tunnel is toggled carefully on and off—just remember that fake-ip answers are supposed to look weird from the outside.
Routing-shaped pain is quieter in the log but loud in behavior: you see a successful policy pick, yet the site is wrong-region, dead, or corporate-blocked because the flow went DIRECT when you assumed tunnel. Many GUIs annotate the matched rule or final policy; treat that annotation as ground truth. If your rule stack says DIRECT for a CDN edge you did not expect, the engine is doing exactly what you asked. The bug is the earlier broad GEOIP or DOMAIN-KEYWORD line, not the node.
TLS or SNI-shaped pain tends to read like handshake failures, certificate mismatch, or abrupt resets right after ClientHello. Those can be middleboxes, antivirus HTTPS inspection, or a node that speaks the wrong ALPN for the port you dialed. They are usually not fixed by “pick another country” unless your second hop genuinely avoids the broken path.
Dial and transport pain is the classic timeout, connection refused, or “i/o timeout” after a group is chosen. That is where node health, UDP blocking, QUIC fallback, and congestion matter. Before you declare the node dead, confirm the log shows the tunnel path was actually selected; otherwise you are stress-testing your ISP exit for no reason.
Step two: DNS mode is not cosmetic; it changes what rules see
Modern Mihomo-class cores can front applications with redir-host or fake-ip style DNS semantics (exact feature names differ slightly by client export, but the idea is stable). The recurring failure mode is simple: your mental model still assumes public A/AAAA records everywhere, while the engine is operating on an internal mapping optimized for routing speed. When those two worldviews diverge, domain rules appear “broken” even though the YAML is syntactically perfect.
If you use fake-ip, remember that some matchers and diagnostics behave differently than they do on a vanilla resolver. That is not a moral judgment; it is a reminder to read the log’s resolved value rather than assuming Chrome’s DevTools always shows the same address your policy engine used for matching.
Practical stabilization tips: keep a short list of domains that must bypass fake-ip if your profile supports it, keep upstream nameservers reachable on your current network, and avoid chaining three different “smart DNS” layers unless you enjoy philosophical puzzles. For a deeper performance-oriented tour of DNS in real profiles, the connection optimization article walks latency trade-offs that overlap with “why does this feel offline” symptoms.
Step three: hunt accidental DIRECT before you blame the airport
Most “connected but nothing loads” cases are not exotic. They are a catch-all rule that sends more than you thought to DIRECT, combined with a network where direct access to certain CDNs is flaky. The engine is healthy; the policy is just conservative in a way that hurts you today.
Work top-down in the rules: list mentally: LAN bypass, explicit allow/deny lists, GEOIP bands, provider RULE-SET sections, then MATCH. The first match wins forever; anything below the winning line is decorative. If your provider merged a new domestic list that now includes a hostname you need tunneled, you will not see a “warning sticker” in YAML—only silent DIRECT in the log.
When you maintain remote lists, ordering is a maintenance task, not a one-time setup chore. The advanced patterns in the rule providers tutorial explain how to keep large RULE-SET stacks from becoming an unreadable sandwich that hides the one line starving your traffic.
Step four: decide whether your apps even see Clash
System proxy mode is quick to try and easy to bypass: some runtimes ignore it, corporate MDM locks it, or a browser extension pins its own proxy. TUN mode captures more traffic because it sits lower in the stack, but it introduces a different class of questions about adapter priority, DNS hijack scope, and coexistence with VPN software. If your logs stay empty while pages fail, revisit coverage before you tune cipher suites.
If you already know you need IP-layer capture, read the dedicated TUN mode guide before you stack two virtual adapters and wonder why only half your packets arrived. TUN does not replace sensible rules; it only ensures more flows are eligible to be classified.
A field checklist you can run in fifteen minutes
One: Confirm the core process is running and the dashboard API responds. If this fails, fix local permissions or port collisions first.
Two: Reproduce with a single URL and capture the log line that names the outbound group and matcher.
Three: If DNS errors appear first, validate upstream DNS reachability and fake-ip settings before touching nodes.
Four: If the outbound is DIRECT but you expected a tunnel, move or narrow the responsible rule, then retest the same URL.
Five: If the outbound is your tunnel yet handshakes fail, test TCP-only targets, try another node in the same group, and consider QUIC or UDP blocking on the access network.
Six: If only one app family fails, suspect split tunnel lists, per-app VPN hooks, or missing environment variables rather than “the internet is down.”
That sequence intentionally delays the dramatic steps. Swapping every line in a thousand-rule profile feels productive; it is usually just expensive noise.
False friends: settings that look relevant but mislead beginners
Latency tests are great for ranking nodes, yet they can be green while browsing fails if your rules send HTTP traffic somewhere latency never measured. Geo auto-selection is convenient until a CDN maps your favorite SaaS into a region your policy stack treats as domestic. Large community lists are educational until they quietly outrank your tiny personal exceptions because you appended them in the wrong band.
When a knob does not change the log, it was not on the critical path. Respect that feedback and return to the decision tree instead of escalating superstition.
When to trust upstream issue trackers—and when not to
Mihomo and popular GUIs move quickly. If your log shows a parser error or a crash loop after an upgrade, upstream release notes matter. If your log shows a calm DIRECT policy pick, upstream cannot fix your ordering mistake with a patch. Keep those boundaries clear so you file useful issues with traces instead of screenshots of a frozen spinner.
Open source repositories are the right place to read code, confirm defaults, and follow breaking changes; they should not be the first hop for downloading installers when you simply need a vetted bundle. Keep those concerns separate even when you are frustrated.
Closing thoughts
Clash-class clients reward a calm diagnostic habit: status lights describe the cockpit, logs describe the runway. When you align DNS reality with rule intent and confirm traffic actually enters the engine you think is steering it, most “connected but offline” mysteries shrink to a single mis-ordered line, a resolver detour, or a handshake shape your network no longer tolerates.
Compared with chasing random toggles, log-first triage saves evenings, keeps profiles maintainable, and makes future upgrades boring in the best way. That stability is the same reason teams standardize on Clash-family cores in the first place: transparent decisions beat opaque magic.
For structured documentation beyond blog posts, the Clash documentation hub collects client notes that complement what you see in the core log.