“Connected” in a Clash client may only mean the core is running, the system proxy is enabled, or a VPN interface has been created. It doesn’t mean the target website is reachable. A node’s latency reading only confirms that a particular test request succeeded. To troubleshoot the full connection, check each link in the chain: whether the app is using the proxy, whether the rules select the right route, whether the node can connect, and whether the domain resolves correctly.
01 | Check your network and determine the scope of the issue
Turn off the system proxy and TUN, then try a website that normally works without a proxy. If it still fails, troubleshoot your Wi-Fi, Ethernet, router, ISP, or campus network sign-in first. Repeatedly updating your subscription won’t help at this stage. Hotel and airport networks may also require you to complete a captive portal sign-in in your browser; using a proxy can get in the way.
- Test a commonly used website in mainland China and the site that originally failed. Note whether all sites fail or only some do.
- Switch to your phone’s hotspot while keeping the same client, configuration, and node. If the hotspot works but your usual network doesn’t, investigate restrictions on that network first.
- Check that your system date, time, and time zone are correct. A significantly incorrect clock can cause TLS certificate validity errors.
Don’t rely on ping alone to determine whether a website is available. The destination may block ICMP, while browsers use TCP 443 or QUIC. Conversely, a successful ping to an IP address doesn’t confirm that HTTPS, certificates, or the proxy connection are working.
02 | Check that your subscription is active and the configuration loaded
Open the client’s subscription or configuration page, manually update the active subscription, and review the update log. Distinguish between a successful download, a successful parse, and a successful configuration switch: receiving a response from the subscription URL doesn’t mean the core accepted its contents as YAML. If the response is a login page, quota notice, or error message, parsing may fail outright.
- HTTP 401 or 403: Check your authorization, subscription token, and provider account status. Don’t assume the subscription has expired based on the status code alone.
- HTTP 200 but parsing fails: Check the response content type, subscription format, and whether your client core supports the protocols and fields it contains.
- Old nodes are still listed: Old configuration data can remain on your device. A node’s presence doesn’t mean your plan is still active; check the expiration date and remaining data too.
- Update completed but nodes haven’t changed: Confirm that the updated configuration is active. If you use
proxy-providers, check the update status of the relevant provider too.
03 | Check node connectivity; latency isn’t a guarantee
Select one node and temporarily avoid automatic selection groups that might switch routes during testing. Test the same destination three times, then compare results with a node in another region or on another route. If only one node fails, investigate that node first. If every node from the same provider fails, check your account, network, and core compatibility next.
A latency test usually requests a specific test URL. Success only means that URL was reachable at that moment. The destination website may have separate access restrictions, and a node may only start dropping packets during peak hours. Check the logs to see whether the failure is connecting to the node server or the node connecting to the destination; these are different points in the connection.
connection refused: The connection was explicitly rejected. Check the server port, service status, or local listener.i/o timeout: The connection or read/write operation timed out. Use the address in the error to determine whether the issue is with the node, DNS, or destination.- TLS handshake failure: Check the system clock, SNI, protocol parameters, and core support. Don’t disable certificate verification as a shortcut.
04 | Match the system proxy port to mixed-port
This is a common reason the client looks fine but the browser’s requests don’t appear in the logs. Check the active configuration for mixed-port; don’t guess the default. The example below uses 7890. If your actual value is 7897, update it in both the system settings and test commands.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
On Windows 11, go to Settings → Network & Internet → Proxy → Manual proxy setup and check the address and port. On macOS, go to System Settings → Network → select your current network → Details → Proxies. If the client manages the system proxy, use its toggle to avoid the client and system settings overwriting each other. external-controller is the management interface, not a web proxy port.
Test with an explicit proxy to bypass browser settings
On Windows, use curl.exe in Terminal; on macOS or Linux, use curl. The command below waits up to 20 seconds and prints the response headers without downloading the full page:
curl.exe -I --connect-timeout 10 --max-time 20 --noproxy "" --proxy http://127.0.0.1:7890 https://example.com/
An HTTP response means the request reached an HTTP response endpoint; 403 doesn’t mean the page is usable. If you see 200 Connection established followed by a TLS error, only the proxy tunnel was established—HTTPS hasn’t necessarily succeeded. If the explicit proxy works but the browser doesn’t, check the browser’s proxy settings, extensions, and secure DNS. If the local port is unreachable, check the core and its listener first.
# Windows PowerShell: find the process listening on port 7890
Get-NetTCPConnection -LocalPort 7890 -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess
# Linux: check listening ports and processes
ss -lntp 'sport = :7890'
# macOS: check listening ports and processes
lsof -nP -iTCP:7890 -sTCP:LISTEN
Confirm that the port is owned by the current client core. If another program has claimed it, close the conflicting program or change the proxy port. Don’t terminate a process just because you found its PID.
05 | Check whether the app is bypassing the system proxy
The system proxy isn’t a universal switch that covers every program. Some games, command-line tools, and apps with their own network stack don’t use it. Browser extensions may also have separate proxy settings. Check the client’s Connections page or logs for a matching destination entry when you make a request.
- Browser: Temporarily disable proxy-switching extensions and check for a separate SOCKS address or bypass list.
- Command line: Check
HTTP_PROXY,HTTPS_PROXY,ALL_PROXY, andNO_PROXYfor an outdated port or exclusion rule overriding the expected settings. - Firefox: Go to Settings → General → Network Settings → Settings and check whether Firefox uses the system proxy or a manual proxy.
In PowerShell, run Get-ChildItem Env:*proxy* to view related environment variables. On macOS or Linux, run env | grep -i proxy. Output may contain credentials, so redact it before sharing. Avoid running multiple VPNs, proxy extensions, and network accelerators at once: your packets end up changing trains, and your troubleshooting notes lose track of the stations.
06 | Check TUN permissions, services, and route handling
If an explicit HTTP proxy works but your connection drops only when TUN is enabled, the node may be fine. Check the virtual network adapter, routes, and permissions instead. Windows clients commonly require service mode or administrator privileges; Linux requires the relevant network permissions; macOS requires authorization for network components as specified by the client. Follow the requirements for your specific client.
- Turn off TUN and confirm that the system proxy or explicit proxy can access the internet. Use this as your baseline.
- Check the core logs for errors such as failure to create a virtual network adapter, insufficient permissions, or failure to add a route.
- Temporarily quit other VPNs and virtual networking software, then enable TUN and check whether the default route changes.
- On Android, search for “VPN” in Settings and confirm that the intended client has permission. Always-on VPN and blocking connections without a VPN can also affect switching.
In mihomo, tun.enable, auto-route, and dns-hijack control interface activation, routing, and DNS interception respectively. Enabling the first doesn’t ensure the others are configured correctly. A client may merge and generate these fields, so check the final runtime configuration rather than just the original subscription.
07 | Check rule mode, policy groups, and REJECT matches
Find the failed domain on the Connections page and check its matching rule, policy group, and final node. Rules are evaluated in order, and evaluation stops at the first match. A specific domain may match DIRECT or REJECT earlier in the list, so the fallback rule never gets a chance to run.
Temporarily switch to Global mode and explicitly select a node you’ve already tested. If the site works in Global mode but not in Rule mode, focus on rule order and policy group selection. Global mode only changes routing for traffic that reaches the core; it won’t automatically capture apps that bypass the proxy. Private network and route exclusions under TUN also need to be checked separately.
# Rule snippet: PROXY must be a node or policy group that exists in your configuration
rules:
- DOMAIN-SUFFIX,example.com,PROXY
- GEOIP,CN,DIRECT
- MATCH,PROXY
The example illustrates rule order; it’s not a recommendation to replace your entire rule list. If a website’s main domain works but images or sign-in fail, check related CDN, API, and authentication domains too. After making a change, switch back to Rule mode and keep only the targeted fix instead of relying on Global mode to mask the problem.
08 | Distinguish DNS failures, DNS tampering, and encrypted DNS bypass
Investigate DNS when the logs show a resolution failure or DNS timeout, or when the same domain gets clearly abnormal results on different networks. CDNs may return different IP addresses normally, so a difference between two results alone doesn’t prove DNS tampering. Consider the returned address range, connection errors, and results after switching to a trusted resolver.
First, check which resolver is receiving the query
# Windows: check the response from the system's default DNS resolver
nslookup example.com
# Use only if mihomo DNS is actually listening on 127.0.0.1:1053
nslookup -port=1053 example.com 127.0.0.1
# macOS and Linux: if dig is installed, query the same listening port
dig @127.0.0.1 -p 1053 example.com A
1053 is only an example; it must match dns.listen in the final configuration. The proxy port 7890 is not a DNS port. With fake-ip enabled, an address in the 198.18.0.0/16 range may be an expected mapping, not a sign of a DNS problem. What matters is whether the core continues to handle subsequent traffic.
- Confirm that
dns.enableis enabled, the upstream resolver is reachable, and resolving the proxy server’s domain doesn’t create a dependency loop. - TUN DNS interception usually targets standard queries on port 53. Don’t assume it also intercepts the browser’s built-in DoH in the same way.
- Temporarily set the browser’s Secure DNS or Android’s Private DNS to match your test setup. Change one setting at a time, then restore the settings you need after testing.
- After changing DNS on Windows, run
ipconfig /flushdnsand restart the browser. Clearing the system cache doesn’t guarantee that every app’s own cache is cleared.
respect-rules makes DNS upstream connections follow routing rules, so account for bootstrap settings such as proxy-server-nameserver as well. Don’t pile on multiple fallbacks and upstreams to fix one domain; you’ll lose track of which resolver is actually responding.
09 | Check for isolated IPv6, UDP, and MTU issues
If the home page loads but videos, sign-in, or larger files get stuck, check for protocol-specific issues. Compare results using the same node and URL instead of immediately reinstalling the client. Having an IPv6 address on your system doesn’t mean your network and proxy egress both have a working IPv6 route.
| Symptom | Test | What the result tells you |
|---|---|---|
| Direct IPv4 works, but IPv6 times out | Turn off TUN, then use curl with -4 and -6 to test the same destination directly | Checks the underlying network; doesn’t indicate which address the remote proxy uses |
| Browser fails, but the TCP HTTPS test works | Temporarily disable QUIC in the browser and test again | If it helps, check UDP support and routing; don’t rush to disable it permanently |
| Large transfers stall only with TUN enabled | Back up the configuration, then temporarily set the TUN MTU to 1400 | 1400 is a value to try for diagnosis, not the best setting for every network |
To test direct connectivity on the underlying network, run curl -4 --noproxy "*" -I --max-time 20 https://example.com/, then replace -4 with -6. On Windows, use curl.exe. The destination needs a matching address record. When testing through an HTTP proxy, -4 doesn’t force the remote proxy to use IPv4 to reach the destination; don’t confuse the two tests.
Make sure the client has applied the final MTU setting, then reconnect TUN before testing. Restore the original value if it doesn’t help. UDP issues don’t necessarily prevent all websites from loading: many browsers can fall back to TCP, depending on the network and app implementation.
10 | Use logs to pinpoint the issue and keep a minimal reproduction and recovery plan
If the first nine steps haven’t pinpointed the problem, enable debug logging briefly, reproduce the issue once, then restore info. Read the logs around the same timestamp: the app connection, matched rule, selected node, DNS query, and final error should form a traceable chain. A screenshot of the final “timeout” line alone usually isn’t enough to distinguish a local listener issue from a node connection or destination response failure.
Gather these six details before reporting the issue
- Record the operating system version, client version, and mihomo core version separately.
- Whether you’re using the system proxy or TUN, the actual
mixed-portvalue, and whether any other VPNs are enabled. - Results of the explicit proxy test for the same URL, what happened in the browser, and when you tested.
- A comparison of Rule and Global modes, including the final node—not just the policy group name.
- A comparison of your current network and phone hotspot, and whether the issue changes with the node or network.
- Relevant logs and a minimal configuration snippet with sensitive information redacted. Remove tokens, passwords, subscription links, and private address information.
To check YAML syntax and configuration fields, run mihomo -t -f config.yaml with the same core binary and the correct working directory. Passing the configuration check only means the configuration was accepted; it doesn’t confirm that nodes, upstream DNS, or the destination network are reachable. If you use external rule files, databases, or relative paths, make sure the test environment matches the runtime environment.
The goal of these ten checks isn’t to flip every switch. It’s to verify each part of the connection in turn: network → active configuration → local listener → app routing → rule selection → DNS and egress. Fix only the link that fails. “Reinstalling seemed to help” may end one incident, but it won’t explain the next one.