Capture the details first: timestamps, request targets, and the active core

A “connected” status in Clash usually means the core is running or the local proxy is enabled. It doesn't mean every website can connect. Trace the request path to diagnose the issue: did the app send traffic through the proxy? Did DNS resolve the hostname? Which rule and policy were selected? Did the node connect, and did the remote server respond?

Log formats vary across Clash, Clash Meta (now generally maintained as the mihomo core), and different GUI clients. The examples below illustrate common fields and error snippets; they aren't exact output for any particular version. First, note the core name and version from the client's About or core information page. Troubleshoot against the documentation for that core, not just the GUI client version.

  1. Record the time: Include seconds, for example, 14:32:10. Save relevant errors before clearing the log view.
  2. Limit the test: Pause downloads and background updates, then open just one affected site to avoid mixing dozens of concurrent connections.
  3. Record the environment: Note the OS, client and core versions, rules or global mode, system proxy and TUN settings, and the active policy group and node.
  4. Change one thing at a time: Make a new request after each change and compare results for the same destination. Don't change DNS, the node, and the rules all at once.

Log levels: use info for everyday use and debug briefly when reproducing an issue

View output in the client's Logs or Runtime Logs page. The log-level setting may be under Settings or Core Settings, depending on the client. Filtering the log view doesn't necessarily change the core's output level: filtering for “debug” can't show records the core never generated.

Clash and mihomo commonly use the top-level log-level field, with values silent, error, warning, info, and debug. The snippet below must be merged into your current configuration; it isn't a standalone subscription:

# Top-level field, at the same level as mode and rules
log-level: debug

After saving, reload the configuration or restart the core as required by your client, then confirm the new setting took effect. Subscription updates may overwrite direct edits; if the client supports overrides or configuration merging, use that instead. Once you've reproduced the issue, switch back to info rather than leaving verbose debug logging on.

Read a connection log: start with the destination, then check the rule and outbound

A single entry may include the source address, destination hostname, matched rule, policy group, selected node, and error. Read it in order: whether the log shows DIRECT or a proxy node before the error determines which part of the connection path to investigate next.

# Illustrative fields; log formats vary
[TCP] 127.0.0.1:53124 --> example.com:443
match DomainSuffix(example.com)
using Proxy[Node A]
error: dial tcp 203.0.113.10:443: i/o timeout

Here, 53124 is the temporary source port used for this connection by the app, not the port to enter as the system proxy listener. example.com:443 is the destination, and Proxy is the policy name. The documentation-only address 203.0.113.10 is for illustration and must not be used for connectivity tests.

Log clueWhat to check firstRelated setting or entry point
No new connection appearsIs the request reaching the local proxy?System proxy, mixed-port, TUN, app settings
Destination hostname fails to resolveWhich part of DNS resolution failed?dns, node hostname resolution, system resolver
Matched DIRECTIs the routing behavior expected?mode, rules, rule providers
Times out through the proxyIs the node endpoint or final destination unreachable?proxies, proxy-groups, node service status
Listener fails to startIs the port already in use?mixed-port, port, socks-port, controller port

Dial timeouts: distinguish a timeout connecting to the node from one connecting to the destination

dial timeout, i/o timeout, and context deadline exceeded all mean an operation didn't finish in time, but a timeout alone doesn't prove that DNS is at fault. Check the address on the same log line and the entries around it. If the failed address is the node server, focus on the path from your device to the node. If it's the destination reached directly, check the direct connection and routing rules.

Narrow it down in four steps

  1. Manually select a different node in the policy group, then retry the same request. If it works through another node, the issue is more likely with the original node or its route, but that alone doesn't prove the protocol is at fault.
  2. Try a different website. If only one destination fails, check its status, regional access restrictions, and the route from the node to that site.
  3. Keep the node unchanged and switch networks, for example from Wi-Fi to a mobile hotspot. If the result changes, focus on the local network, firewall, or ISP route.
  4. Check the server address, port, and protocol settings in the node configuration. An expired subscription or a server-side port change can also prevent connections. Update the subscription and confirm your account status before editing the configuration.

A successful latency test only means the test destination responded to that particular probe at that time. It doesn't guarantee that streaming, downloads, or UDP will work. An 80 ms test result doesn't mean a web page will necessarily load in 80 ms.

Connection refused is different from a timeout

connection refused usually means the connection was actively rejected—for example, no service is listening on the destination port, or a firewall returned a rejection. If the address is 127.0.0.1:7890, first check whether a local proxy is listening on that port. If it's a node server, verify the node port and service status. Increasing the timeout won't fix a refused connection.

DNS failures: distinguish the destination hostname, node hostname, and upstream resolver

Messages such as no such host, lookup ... failed, and DNS query timeout point to name resolution, but you still need to identify what failed. The destination hostname needs to resolve, and so does a proxy server specified by hostname. An encrypted DNS upstream specified by hostname also needs its own address resolved first.

On Windows, start with nslookup example.com. On macOS or Linux, run dig example.com after installing the relevant tool. These commands typically use the system's DNS resolution path, not necessarily Clash's built-in DNS. Test system and core DNS separately.

A Fake-IP address alone doesn't prove DNS is failing

In Fake-IP mode, an app receiving a synthetic address can be expected behavior. Common configurations use the 198.18.0.0/16 range, which isn't a real public website address. Check whether the connection reaches the core and the hostname mapping is restored; don't switch nodes just because you see this address.

If the issue started after changing DNS mode, reconnect the app first and, if needed, flush the system DNS cache. Don't immediately add every hostname to fake-ip-filter. Test one domain that's actually incompatible, then make the smallest necessary change. See the DNS configuration reference and Fake-IP guide for field details.

Rules not matching: check the mode, rule order, and hostname visibility

Unexpected routing doesn't always produce an error in the logs. The request may have matched an earlier direct rule, or the client may be in global mode and not using the rule list as expected. Check the running mode first, then inspect the actual rule and policy shown in the connection details.

# Routing example; Proxy must match an existing policy name
mode: rule
rules:
  - DOMAIN-SUFFIX,example.com,Proxy
  - GEOIP,CN,DIRECT
  - MATCH,Proxy

Rules are evaluated from top to bottom, and evaluation stops at the first match. If you put MATCH,DIRECT on the first line, none of the domain rules below it will take effect. Proxy in this example isn't a built-in reserved name; it must exactly match the name of an existing proxy or policy group in your configuration.

  1. Check the rule mode: Global mode typically uses a global policy to select the outbound route, while Direct mode bypasses the expected proxy policy. See proxy mode settings.
  2. Check the active configuration: Make sure you're editing the configuration currently in use. Confirm that custom rules remain after a subscription refresh.
  3. Check rule provider status: For RULE-SET, confirm the provider loaded successfully and that its name and content format match the configuration.
  4. Check hostname visibility: If an app connects directly to an IP address, hostname rules may not match. Sniffing can provide hostname information in some cases, but it can't recover the hostname for every connection.
  5. Reconnect: Existing long-lived connections may keep using their original outbound route. Close the relevant page or app connection before testing, so you don't mistake an old connection for the result of a new rule.

Startup and permission errors: port conflicts, invalid configuration, and TUN

address already in use: find out what's using the port

If the core fails to start with bind: address already in use, first identify whether the port belongs to the proxy, DNS listener, or controller. The commands below use 7890 as an example. Use the port in your current configuration; defaults vary by client.

# Windows: check the listening port and process ID
netstat -ano | findstr :7890

# macOS: find the process listening on a TCP port
lsof -nP -iTCP:7890 -sTCP:LISTEN

# Linux: inspect listening TCP sockets
ss -ltnp 'sport = :7890'

Once you've identified the process, quit any duplicate client instance or change the local listening port. If you change mixed-port from 7890 to 7891, update the system proxy and any in-app proxy settings too. Don't terminate an unknown system service just because you found its process ID.

YAML and policy reference errors: get the configuration to load first

yaml: line ... usually points to a syntax or structure issue. Indent with spaces, not tabs, and quote values containing special characters according to YAML rules. The reported line may only be where the parser could no longer continue; the actual error may be on the preceding line. A missing policy or misspelled rule provider name is a configuration reference error, not something a network restart can fix.

TUN permission denied: check system authorization and traffic capture

TUN creation can fail due to missing administrator privileges, the client's service mode, or OS-level VPN authorization. On Windows, check the service and whether the client is elevated. On Android, make sure you've approved the VPN request. Follow the client documentation for platform-specific steps. Enabling TUN doesn't automatically route all traffic through the proxy; routing, exclusions, and existing VPNs all affect what gets captured.

If an explicit proxy works but TUN doesn't, keep the same node and configuration and change only the traffic capture method for comparison. This helps isolate issues with the virtual interface, routing, or DNS capture instead of raising doubts about the subscription and node at the same time.

Verify the fix: compare before and after using the same request

Fewer log entries don't mean the problem is fixed. After making a change, retest with the same destination, network, and node. Confirm the request used the expected policy and received an application-level response. Browsers may cache pages, so it's best to send a fresh request. From a terminal, specify the local proxy explicitly to avoid interference from environment variables.

# Test an HTTP proxy when the local mixed-port is 7890
# On Windows, use curl.exe
curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com/

# Test SOCKS when the mixed-port or SOCKS listener is 7890
curl --proxy socks5h://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com/

socks5h sends the hostname to the SOCKS proxy for resolution, making it useful for comparison with local DNS. If the test returns an HTTP response such as 403, an HTTP endpoint responded, but the destination may still restrict access. That's different from timing out before a connection is established.

If you still need to report the issue, prepare a concise record: OS and core versions, reproduction steps, timestamps, redacted logs, relevant configuration snippets, and the individual checks you've already tried. This is more useful than a full-screen screenshot and makes it easier to pinpoint whether the issue lies in DNS, rules, the listener, or the node connection.