Clash runtime logs: how to troubleshoot DNS errors and connection timeouts

Learn how to adjust log levels, read each field, and distinguish dial tcp timeout from dns resolve failed. A practical guide to common errors and a troubleshooting sequence that narrows the cause.

First identify whether the log comes from the interface, the core, or the operating system

When a Clash client reports “connection failed,” the interface notification usually shows only the outcome. The runtime log is what helps identify the cause. Clash Meta (now called Mihomo) handles DNS, rule matching, node connections, and TUN forwarding, while the desktop client starts the core, changes system proxy settings, and displays logs. Either layer can report an error, so the first step is not searching for one English line but determining which layer failed.

Log source Common entries Check first
Client interface logs Core startup failures, configuration save failures, service mode installation results Client permissions, core path, configuration file
Mihomo runtime logs DNS queries, rule matches, proxy dialing, connection timeouts Subscription configuration, nodes, DNS, and network egress
Operating system logs TUN interface creation failures, port conflicts, permission denials Administrator permissions, firewall, existing processes

Most desktop clients let you view core output directly from the “Logs” page in the sidebar. In a typical Mihomo desktop client, open “Settings” → “Clash Settings” → “Log Level,” temporarily change the level from info to debug, then return to “Logs” and reproduce the issue. Menu names vary slightly between clients, but the standard configuration field is usually log-level.

log-level: debug

Keep the complete timeline when reproducing the issue

Do not capture only the last red error. A connection typically passes through DNS resolution, rule matching, policy-group selection, node dialing, and the TLS handshake; the final line shows only where the process stopped. Clear the current log first, note the system time, perform one failed action, and keep at least 10 seconds of entries before and after the error.

  1. Close video streaming, sync, and download programs that are actively using the network to reduce unrelated entries.
  2. Clear the client log and confirm that the current configuration loaded successfully.
  3. Visit only one test address, such as https://example.com.
  4. Record the access time, selected policy group, and node name.
  5. Export or copy the complete section from the DNS query through the end of the connection.

Which fields should a Clash log line contain?

Display formats vary between Mihomo versions and client wrappers, but the core information is largely the same: time, level, network type, source address, destination address, matched rule, and the final outbound policy. Here is a typical TCP connection entry.

time="2026-07-27T14:32:18.412+08:00" level=info msg="[TCP] 127.0.0.1:53124 --> example.com:443 match DomainSuffix(example.com) using PROXY[HK-01]"

If the log shows using DIRECT, the rule classified the connection as direct. If it shows using REJECT, the configuration actively rejected the request. Switching nodes usually will not change the result; first check rule order, rule-set contents, and the current operating mode. Rules are matched from top to bottom, and a connection that already matches an earlier rule is not checked against later rules.

How to read info, warning, error, and debug

Level Purpose Does it always indicate a failure?
info Configuration loading, connection establishment, rule matches No; mainly useful for tracing the flow
warning Retries, compatibility fallbacks, rule-set update issues Not necessarily; check whether functionality is affected
error Dial failures, resolution failures, configuration load failures Usually requires attention
debug More detailed DNS, connection, and protocol status No; it simply contains more information

DNS errors: distinguish upstream failures from local listener failures

dns resolve failed, lookup failed, and exchange failed all mean that the domain-resolution path did not return a valid result, but the underlying causes may be completely different. A common flow is: the application sends the query to the system or Mihomo, Mihomo then contacts the configured nameserver, and the result is processed according to fake-ip or redir-host mode. If any link breaks, the interface may show only “DNS failed.”

Check the upstream DNS when you see a timeout

level=error msg="dns resolve failed: lookup example.com: i/o timeout"
level=warning msg="[DNS] exchange failed: context deadline exceeded"

i/o timeout or context deadline exceeded means that no valid response arrived before the deadline. First check whether the DNS addresses in the configuration are reachable from the current network. If you use DoH, also confirm that its hostname can be resolved by default-nameserver; otherwise, you can create a circular dependency in which the DoH hostname must be resolved using the very resolver that is supposed to provide access to DoH.

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  default-nameserver:
    - 223.5.5.5
    - 1.1.1.1
  nameserver:
    - https://dns.alidns.com/dns-query
    - https://1.1.1.1/dns-query

This example makes the local DNS listener available at 127.0.0.1:1053 and provides a bootstrap resolver for the DoH hostname. Adjust upstream addresses for your network; an upstream reachable on one network may be unreliable or inaccessible on the current Wi-Fi, corporate network, or mobile hotspot.

Confirm that the local DNS port is actually listening

If the log shows bind: address already in use, another process is using the listener port required by the configuration. Port 53 is commonly used by the system DNS service, and ordinary user processes may also lack permission to bind low-numbered ports on some systems. On a desktop, use 1053 instead, then let the client or TUN DNS hijacking handle the queries.

dig @127.0.0.1 -p 1053 example.com

nslookup example.com 127.0.0.1

The dig command explicitly specifies port 1053 and is suitable for macOS or Linux systems with the corresponding tool installed. Windows’ built-in nslookup cannot conveniently specify a non-53 port, so first check the default listener. If the configuration uses 1053, confirm successful binding in the client log or verify it with a port-checking tool.

dial tcp timeout: node, network, or destination site?

dial tcp timeout means that the TCP dialing phase did not complete within the time limit. Focus on where the connection is being dialed: if the destination is the proxy server’s IP and port, the problem is likely between the local machine and the node; if the proxy connection is already established and the client is connecting to the destination site, the issue may involve the node’s egress, the destination site, or rule selection.

level=error msg="dial tcp 203.0.113.20:443: i/o timeout"
level=error msg="connect failed: dial tcp: lookup node.example.net: i/o timeout"
level=error msg="dial tcp 127.0.0.1:7890: connect: connection refused"

Use the local proxy port for repeatable tests

Assuming the configuration sets mixed-port to 7890, first confirm the port, then make a command-line request explicitly through Clash. The request below sets a 5-second connection timeout and a 15-second overall limit, making it easier to distinguish an immediate refusal from a timeout after prolonged waiting.

curl --proxy http://127.0.0.1:7890 \
  --connect-timeout 5 \
  --max-time 15 \
  -I https://example.com

If the command returns Connection refused in under a second, check the core process and local port first. If it reports a connection timeout after about 5 seconds, the local port usually accepted the request, so the problem is more likely in the node dialing stage. If it returns HTTP/2 200 or HTTP/1.1 200 OK, the test address can be reached through the current proxy; the original application may instead be affected by proxy overrides, QUIC, certificates, or its own DNS.

In Windows PowerShell, run the following command first to check whether the local port is reachable:

Test-NetConnection 127.0.0.1 -Port 7890

Seeing TcpTestSucceeded : True only means that the local machine can connect to Clash’s listening port; it does not prove that the remote node works. Continue by checking the policy group, node name, and remote errors in the core log.

The difference between connection refused and network unreachable

Error What it means First action
connection refused The destination host explicitly refused the connection, or no local process is listening Verify the IP, port, core process, and node service status
i/o timeout The read or write operation did not complete before the deadline Test the network egress, switch nodes, and compare latency
network is unreachable The system has no usable route to the destination network Check network interfaces, IPv4/IPv6 routes, and TUN status
TLS handshake timeout The TLS handshake after TCP did not complete in time Check link quality, system time, protocol parameters, and intermediate networks
EOF The peer closed the connection prematurely Check whether it happens repeatedly and compare other nodes

How to interpret TUN mode logs

System proxy settings affect only applications that actively read those settings, while TUN mode captures a much broader range of traffic through a virtual network interface. When the browser works but a game or terminal does not, check whether the log contains connection entries for that process: no entry usually means the traffic has not reached Mihomo; a matched rule followed by a dialing failure indicates a problem inside the proxy path.

Common TUN startup errors include operation not permitted, failed to create tun device, and route-write failures. They usually point to permissions, service mode, or virtual interface state. On Windows clients, check whether “Settings” → “Service Mode” is working correctly, then enable TUN again. On macOS and Linux, confirm that the client or core can create virtual interfaces and modify routes.

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

auto-detect-interface lets Mihomo identify the current default egress. After frequent switches between Wi-Fi, Ethernet, VPN, or a mobile hotspot, if the log still shows the old interface, disable TUN, wait for the system routes to stabilize, and enable it again. Do not let two network tools write default routes and DNS hijacking rules at the same time; the log may otherwise alternate between unreachable-interface and DNS-timeout errors.

What it means when the log contains no destination connection

Handle configuration and subscription errors during startup

If the core has not finished loading the configuration, later DNS and node tests are meaningless. YAML is sensitive to indentation, and malformed list items, colons, or string syntax can all prevent startup. Log entries such as parse config error, yaml: line 42, or mapping values are not allowed often point near the error, but the actual problem may be on the preceding line.

proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - Auto
      - DIRECT

Use consistent spacing at the same indentation level and do not mix tabs with spaces. Quote names containing colons, hash signs, or other YAML special characters. After a subscription update, if you see provider not found, a missing policy-group reference, or a rule-set loading failure, verify that the referenced names exactly match the keys under proxy-providers and rule-providers, including capitalization and spaces.

HTTP status codes can narrow down a subscription update failure

A troubleshooting sequence from symptom to conclusion

The value of logs is not listing every error; it is finding the first point where the normal flow diverged. One failure may produce DNS timeouts, node test failures, and rule-set update failures at once. If the local machine is already offline, all three are different symptoms of the same root cause. A fixed sequence prevents endless switching between unrelated settings.

  1. Check the basic network: disable the system proxy and TUN, then test whether the current network can access a site that is allowed to connect directly.
  2. Check configuration loading: look for YAML parsing errors, port conflicts, or provider-reference errors during startup.
  3. Check the local listener: verify actual ports such as mixed-port: 7890, then test whether the local machine can connect.
  4. Check DNS: see whether the node hostname and destination hostname resolve, distinguishing a local listener failure from an upstream timeout.
  5. Check the matched rule: confirm whether the destination uses DIRECT, REJECT, or the expected policy group.
  6. Check node dialing: compare errors and timing across nodes in two different regions to determine whether only one node is affected.
  7. Check application interception: when no destination entry appears in the log, review system proxy settings, environment variables, TUN routes, and the application’s own proxy settings.
  8. Restore normal settings: change the log level back to info after testing and remove temporary proxy environment variables.

For example, a browser reports that it cannot connect, and the log first shows lookup node.example.net: i/o timeout, followed by speed-test failures for multiple nodes. The shared failure point is node hostname resolution, so changing each node’s protocol is not the right approach. In another case, the log clearly shows match MATCH using PROXY[US-02], followed by connection refused only for US-02. If switching to HK-01 succeeds immediately, the issue has been narrowed to one node or its port.

The final report should include at least the client version, Mihomo core version, operating system, network type, current mode, log level, reproduction time, and the complete error excerpt. Version information can show whether configuration fields are supported, while the network type helps assess IPv6, corporate network restrictions, or hotspot switching. Once you answer four questions—did the traffic enter Clash, did DNS complete, which rule matched, and which egress was dialed—most runtime failures can be narrowed from the vague “proxy does not work” to one verifiable step.

Download Clash