Reading Clash Logs: Log Levels, Common Errors and How to Diagnose Them
How to read info, warning and error log levels, what DNS failures, handshake timeouts and unmatched rules mean, and how to trace config issues from logs.
Log levels and how to read them in order
Clients built on the mihomo core continuously output logs during startup and operation. Log levels are usually split into five tiers — silent, error, warning, info, debug — controlled by the log-level field in the config file. The levels are inclusive: choosing info outputs info, warning, and error content together, while debug includes everything, producing the largest and most detailed output.
When troubleshooting, it's not a good idea to dive straight into debug logs — the sheer density of information actually slows down diagnosis. A better order is: first check whether there are error-level messages during startup to confirm the core launched correctly; then look at warning messages during connection attempts to judge whether the issue is at the network layer or the rule layer; and only if neither step gives a lead, switch to debug to reproduce a specific request and check line by line whether domain resolution, node selection, and rule matching happened in the expected order.
The debug level records extensive connection detail, and leaving it on long-term will significantly increase log file size. Switch back to info or warning once the issue is located.
Common errors explained one by one
The following error types appear most frequently in logs. Understanding what triggers them is more useful than memorizing the exact wording.
DNS resolution failure
Log lines like "resolve host failed" or "dns resolve error" usually mean the nameserver in the config isn't responding properly, or the target domain isn't covered by the resolution scope at all. This tends to happen in three scenarios: an unreachable custom DNS server, a mistyped DNS-over-HTTPS address, or a rule that sets no-resolve on a domain that still needs outbound resolution. Check by testing the addresses in the nameserver list directly with the system's network tools, then confirm whether the domain-matching type used in the relevant rule set is correct.
Handshake timeout
Errors like "handshake timeout" or "dial tcp timeout" mean the connection setup between the client and the proxy node timed out before actual data transfer even began. Common causes include the node's server being offline, outdated port information in the subscription link, local network restrictions on specific ports, or an unstable network path to the node's region. When this happens, try switching to a different node in the subscription first — if multiple nodes all time out, the problem is more likely with the local network environment than the subscription itself.
Unmatched rules and fallback policy
If a domain repeatedly ends up falling through to the policy group tied to the MATCH or FINAL rule, it means none of the rules above it matched. That's not necessarily a bug, but if that domain was supposed to hit a specific rule, it means the rule order or matching type is wrong. mihomo matches rules top to bottom, and once a rule matches, it stops checking further — so broader rules should always sit below narrower ones, otherwise the narrower rule never gets a chance to take effect.
Connection refused and port conflicts
"connection refused" usually means nothing is listening on the target port, or the local proxy port conflicts with another program. If the log reports a port already in use during startup, check whether multiple client instances are running at once, or whether another tool on the system is using the same mixed port.
Tracing config issues back from log errors
A log error is just a symptom — the real work is connecting that symptom to a specific field in the config file. One practical workflow:
- Confirm at which stage the error occurred — during core startup or when a specific connection request was made. These call for completely different troubleshooting scopes.
- Note the domain or IP involved in the error, then search the config file for rule entries that could match it, and check whether the matching type is what you expect.
- If you suspect a node issue, switch the policy group to a single node for testing to rule out interference from round-robin behavior across multiple nodes.
- If the log points to a DNS-layer error, verify the
nameserverandfallbackfields in thednsblock on their own, temporarily swapping in a public DNS address for comparison if needed. - Once the issue is found, change only one setting at a time and restart to verify, rather than changing several things at once and losing track of which change actually fixed it.
| Log keyword | Likely cause | Where to look |
|---|---|---|
| resolve host failed | DNS server unreachable or domain misconfigured | Check nameserver and domain rules |
| handshake timeout | Node unavailable or unstable link | Switch nodes, check subscription validity |
| connection refused | Port not listening or local port conflict | Check mixed port and other processes |
| MATCH / FINAL hit | Earlier rules didn't take effect | Check rule order and matching type |
Configuration tips for more readable logs
For everyday use, keep log-level at info — this level shows the key connection states without being buried under excessive debug detail. If the client supports viewing logs directly in the interface, prefer the in-app live log panel, which usually scrolls in chronological order and is more intuitive than opening a log file manually. For intermittent issues, fix a reproduction routine first, note the timestamps around when it happens, then filter the log by that time range afterward — this considerably narrows down the search.
Also, after updating rule sets or subscription content, it's worth reviewing a round of logs to confirm the new rules take effect in the expected order, rather than discovering routing problems by accident during actual use. Making log checks a standard step after every config change catches most issues caused by rule ordering or field typos before they cause real trouble.
Download the Clash iOS Client
After getting the client via TestFlight or the App Store, use the runtime logs to verify that your subscription and rule configuration are working as expected.