1. Capture logs: reproduce the request, then increase the log level
Logs in the Clash client interface and logs from the running core cover different layers. The interface may log subscription downloads, service startup, and configuration merges; core logs mainly cover listening ports, DNS, rule matching, and outbound connections. If a webpage will not load, first confirm that the core has started, then check whether the request reached it. A screenshot of an error in the client interface alone is usually not enough to identify a node or rule issue.
Capture a minimal reproduction
- Record the client name and version, plus the core name and full version number. The original Clash and mihomo support different fields, so “latest version” is not specific enough.
- Record the active configuration name and operating mode, and whether the system proxy or TUN is enabled. Use Rule mode to troubleshoot rules; Global mode bypasses the rules you may be trying to test.
- Clear the current log view and note the time. Visit just one problematic address, wait about 10 seconds, then stop refreshing and save the logs from that same time window.
- Check the connection list for the destination, matched rule, policy group, and final node. Use it to fill in outbound details that the logs do not show.
To capture more detail, change the log level on the current client's log page. If there is no setting there, use the configuration editor or override feature supported by the client to set the fields below. Subscription clients may regenerate the runtime configuration, so verify the effective values; editing a cached subscription file that will later be overwritten is not enough.
log-level: debug
| Level | Typical use | What to look for |
|---|---|---|
debug | Briefly reproduce a hard-to-diagnose issue | DNS, connection, and core-level diagnostic details |
info | Monitor routine operation | Startup information, rule matches, and connection records |
warning | Filter for unusual events | Failed connections and resource-loading errors |
error | Focus on more serious errors | Configuration loading and critical component errors |
silent | Disable routine log output | Not suitable for reproducing an issue |
The core determines the level of each message; warning does not necessarily mean the entire proxy service has stopped. Once you have reproduced the issue, restore the level to info. Before sharing logs, redact tokens in subscription URLs, node passwords, controller keys, and personal access domains. Keep the ports, error types, and rule order.
2. dial tcp timeouts: distinguish node connections from destination connections
dial tcp means the program is opening a TCP connection. It does not mean there is a DNS problem, and those words alone do not prove that a node is down. The key is the address that follows: is it the proxy server, the direct destination, or the next hop in a proxy chain? The snippets below illustrate error formats only; their addresses are documentation examples, not working nodes.
dial tcp 192.0.2.10:443: i/o timeout
dial tcp 192.0.2.10:443: connect: connection refused
dial tcp [2001:db8::10]:443: connect: network is unreachable
How to troubleshoot three common errors
i/o timeout: A connection or read/write operation did not complete before the deadline. Check the node address and port on that line, the outbound interface, and the network path. Do not mask the problem by simply increasing the timeout.connection refused: The connection was explicitly rejected. First check the port, whether the remote service is listening, and any rejection rules on your device or an intermediary.network is unreachable: The current network stack has no available route. If the destination is an IPv6 address, check the system's IPv6 routing before blaming the node password.
If the error points to a node server, switch to another known-working node in the same policy group and retry the same destination. If only one node fails, check its server hostname, port, and protocol settings. If several nodes fail at once, check the local network, node hostname resolution, and proxy loops. A successful latency test only confirms that the test request worked; it does not prove that every website or UDP traffic will work.
If the connection list shows DIRECT, the failing request may be taking a direct route to the destination website. Check the matched rule first; do not reinstall the client without evidence. Rules are evaluated in order: an earlier DOMAIN-SUFFIX rule or rule set may already determine the outbound route, and a later MATCH rule will not change it.
3. DNS resolution failures: check each step in the resolution chain
no such host often means the name does not exist or the resolution chain returned a negative response. lookup ... i/o timeout more often means the DNS request did not receive a timely response. SERVFAIL means the resolver could not complete the query. These are different signals; switching proxy nodes is not a universal fix.
First identify the hostname being resolved
- Destination hostname: Check whether core DNS is enabled, whether the application uses system DNS, and whether Fake-IP requests are actually reaching the core.
- Node server hostname: Check the resolution path for the node hostname. mihomo can use
proxy-server-nameserverto specify a resolver for node hostnames; behavior depends on the documentation for the core version you are running. - Encrypted DNS server hostname: Check
default-nameserver, which is used to bootstrap resolution. If the upstream resolver's own hostname cannot be resolved, the resolution chain cannot start.
This minimal DNS diagnostic snippet listens on local port 1053. Merge it into the one existing dns mapping and keep any other fields relevant to your setup. It uses regular DNS as a troubleshooting aid; it is not a universal final configuration and will not change system DNS automatically.
dns:
enable: true
listen: 127.0.0.1:1053
enhanced-mode: redir-host
nameserver:
- 223.5.5.5
On systems with dig installed, you can test this listening port directly. The commands below query IPv4 and IPv6 records, respectively. No AAAA record does not mean that A record resolution has failed.
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com AAAA
If a query to the local listening port succeeds but the application still reports a resolution failure, check the application's built-in secure DNS, the browser's DNS cache, and the actual traffic interception path. If the local port query also fails, check whether the upstream DNS server is reachable and whether features such as respect-rules have created a DNS dependency loop. Do not change the upstream servers, Fake-IP, and routing rules all at once, or you will not know which change helped.
4. Port conflicts: identify the listener and the active proxy port
At startup, bind: address already in use usually means the listening address and port are already in use. Windows may also report, “Only one usage of each socket address is normally permitted.” permission denied calls for separate checks of permissions, security policies, or reserved ports; it does not always mean another process is using the port.
Read the specific port from the error line, then find the corresponding configuration field. For example, mixed-port: 7890 provides both HTTP and SOCKS proxy access, while external-controller: 127.0.0.1:9090 is the management interface. They serve different purposes. The ports below are diagnostic examples; use the actual ports in the running configuration.
Windows: find the process listening on port 7890
netstat -ano | findstr :7890
tasklist /FI "PID eq 1234"
The first command may also match a remote port, so check the local address column and the LISTENING state. In the second command, 1234 is an example PID; replace it with the actual process ID from the first command. First close duplicate instances normally through the client. Do not terminate an unknown system process.
macOS and Linux: show TCP listeners only
# macOS
lsof -nP -iTCP:7890 -sTCP:LISTEN
# Linux
ss -ltnp 'sport = :7890'
On Linux, you may need administrator privileges to view processes owned by other users. If you switch to 7891, update the system proxy, browser's manual proxy, or terminal environment variables as well. Changing only the core port leaves applications connecting to the old one. allow-lan controls access from the local network; it does not fix a local port conflict.
5. Configuration errors: check syntax, fields, and references separately
If the configuration will not load, fix the startup error before troubleshooting the network. yaml: line ... usually points to a YAML parsing issue. Messages such as proxy ... not found usually indicate a broken reference. An unsupported protocol type or unrecognized field may indicate a core compatibility issue. Start with the reported line, but remember that the actual indentation error may be just above it.
- Indentation: Use spaces, not tabs. Keep keys at the same level aligned, and leave the space after
-in list items. - Duplicate keys: Do not add a second
dns,rules, orproxy-groupskey at the same level. Different parsers may report an error or overwrite content, so the result is unreliable. - Name references: Policy groups referenced by rules, nodes referenced by policy groups, and rule providers referenced by
RULE-SETmust match their defined names exactly. - Core capabilities: Do not assume that the original Clash can read configurations that use VLESS, Hysteria2, or other features. Check which core is actually running, not just the client name.
- Remote resources: A failed rule set download is a resource-loading problem, not necessarily a YAML syntax error. Check the provider URL, file format, cache path, and network route used for the download.
When running the mihomo core directly, start by testing the configuration. These commands assume the corresponding executable and configuration file are in the current directory. Use a test configuration that closely matches the runtime configuration generated by the client.
# macOS / Linux
./mihomo -t -f ./config.yaml
# Windows PowerShell
.\mihomo.exe -t -f .\config.yaml
A passing configuration test only means that this check found no issue that would prevent loading. It does not guarantee that nodes are reachable or that every rule set will work as expected. If the original subscription passes but the client still fails to start, check the differences introduced by overrides, scripts, and the client's generated configuration. Save a copy before editing, fix one type of error at a time, and test again.
6. System proxy and TUN: compare how the same request is routed
If a browser works but a terminal does not, check whether the application follows the system proxy settings. The system proxy does not automatically capture traffic from every program. TUN involves a virtual network interface, routing, and DNS interception, so there is more to troubleshoot. Do not enable multiple proxy tools and TUN instances at once without first comparing their results.
Test the explicit proxy endpoint first
Assuming the mixed port in the active configuration is 7890, use the request below to rule out differences in whether an application reads the system proxy settings. In Windows PowerShell, use curl.exe to avoid aliases in older environments; on macOS and Linux, you can use curl.
curl.exe -v --connect-timeout 10 --max-time 20 --noproxy "" --proxy http://127.0.0.1:7890 https://example.com/
This command sets a 10-second limit for connecting and a 20-second limit for the entire request so you can correlate it with the log timestamps; these are not measured latency values. If it cannot connect to 127.0.0.1:7890 at all, check the listener first. If the proxy tunnel opens but TLS fails, inspect the handshake. Once you get an HTTP response, check the status code; a response such as 403 does not by itself mean the proxy endpoint is broken.
Then compare TUN routing
If the explicit proxy works but a regular application request fails, focus on the system proxy settings, the application's own proxy settings, and TUN routing. If the issue starts after enabling TUN, temporarily turn it off and compare results through the explicit proxy, keeping a copy of the configuration. Fields to check include tun.enable, auto-route, and dns-hijack; actual support and permission requirements depend on the core, client, and operating system.
Do not assume dns-hijack can intercept all encrypted DNS. Standard DNS hijacking mainly handles matching DNS traffic; an application's own HTTPS DNS requests may take a separate route. If the corresponding connection is missing from the logs, first confirm that the request reached the core. If it did, trace it through rules, outbound routing, resolution, and the handshake.
7. Verify the fix: keep evidence you can reproduce
Before closing the issue, retry the same address that originally failed and confirm that the matched rule and outbound node in the logs are as expected. Seeing one homepage load once does not prove that subscription updates, DNS, and background applications are all working again.
- Startup check: The core finishes loading, the proxy endpoint is listening, and there are no recurring port binding errors.
- Request check: The original request succeeds, and its logs no longer show repeated timeouts or resolution errors.
- Routing check: Direct and proxy rules match the intended policies, and the TUN state matches your needs.
- Configuration persistence: Changes remain effective after restarting the client or updating the subscription; the configuration generation process does not overwrite them.
If you still need help, provide the client and core versions, operating system version, time of reproduction, destination type, relevant configuration snippets, surrounding log lines, and tests performed one at a time. This is more useful for diagnosis than a screenshot of the final timeout line alone. See the Protocol Reference for field definitions, and the Quick Glossary for explanations of routing rules, DNS, and TUN.