01 / Proxy Group Design
Proxy Group Types and Practical Combinations
Proxy groups sit between rules and individual proxies. Rules determine what kind of traffic a connection belongs to; proxy groups determine which proxy to use, whether to run health checks, and how to switch when a member fails. The key to maintainable configuration is not putting every node into one group, but creating stable abstraction layers by purpose. For example, rules can refer only to “Websites Outside Mainland China,” “Streaming,” “Messaging” and “Fallback Traffic.” Even when subscription node names change, the rules layer does not need to be rewritten.
select, url-test, fallback and load-balance
select is a manual selection group for situations where you need explicit control over the exit. It does not assess node quality or automatically switch to another member when the current one is unavailable, so it is usually better to put several automated groups inside select rather than only raw nodes. url-test periodically tests members against a specified URL and selects the one with the better result. The test reflects connectivity to that URL, not the actual speed of every destination. Testing too frequently also creates extra connections and is especially unnecessary on mobile networks.
fallback selects the first available member in order, prioritizing a predictable primary-and-backup relationship rather than the lowest test latency. It is easier to predict than url-test when a fixed line should be primary and another should serve as backup. load-balance distributes connections across multiple members, which suits high concurrency when the service permits changing exit locations. Sites with strict login, payment or fraud controls may treat rapidly changing exits as suspicious, so load balancing should not be the default for all traffic.
| Type | Selection method | Best for | Main limitation |
|---|---|---|---|
select |
Manual member selection | Main entry point, region selection and temporary switching | Failed members usually require manual intervention |
url-test |
Automatic selection after periodic testing | Automatically choosing the best node for a purpose | Test results do not represent every real-world service experience |
fallback |
Select the first available member in order | Fixed primary and backup routes | The ordering itself is part of the strategy |
load-balance |
Distribute connections across members | Concurrent downloads and spreading connections | Not suitable for sessions that require a stable exit |
Build a stable two-tier proxy strategy
A common structure uses the first tier to select automatically by region or route characteristics, and the second tier to select manually by business purpose. In the example below, “Auto Select” filters nodes from a subscription provider, while “Websites Outside Mainland China” lets you switch between Auto Select, Failover and DIRECT. The benefit is that rules need to reference only “Websites Outside Mainland China”; everyday adjustments stay in the proxy groups instead of tightly coupling the rules file to one subscription provider.
proxy-groups:
- name: Auto Select
type: url-test
use:
- provider-main
url: https://www.gstatic.com/generate_204
interval: 600
tolerance: 80
- name: Failover
type: fallback
use:
- provider-main
- provider-backup
url: https://www.gstatic.com/generate_204
interval: 600
- name: Websites Outside Mainland China
type: select
proxies:
- Auto Select
- Failover
- DIRECT
use references proxy providers, while proxies lists specific proxies or other proxy groups. Use filter to select subscription nodes, but write regular expressions around stable keywords rather than decorative characters that may change in a subscription name. When node names cannot reliably identify their purpose, manual selection is preferable to a broad expression that may capture the wrong nodes.
After changing proxy groups, check all references: every rule target must exist, every group member must exist, and groups must not reference one another in a loop. If the client reports a configuration parsing error after import, temporarily remove the new groups and restore them section by section. A proxy group does not change the connection path until it receives traffic, so troubleshooting should also use logs to confirm that the final rule actually points to that group.
02 / Rule Management
Rule Providers and Matching Order
Clash processes rules from top to bottom and stops at the first match. Order matters more than rule count: an exact domain loses its purpose if it comes after a broad suffix rule, while LAN and direct-connect services placed after wide proxy rules may be captured too early. The final rule is typically MATCH, which catches connections not covered above and ensures every connection has a defined destination.
Inline Rules and Rule Providers
A small set of rules closely tied to your environment belongs in the main configuration’s rules, such as home storage devices, development domains and a website that must always connect directly. Larger public rule sets that need regular updates are better handled by rule-providers. Rule providers separate rule content from the main configuration and can define a download URL, local cache path, format and update interval. When an update fails, the core will usually continue using the cached rule file, so the cache path must be writable and different providers must not point to the same file.
rule-providers:
private-direct:
type: http
behavior: domain
format: yaml
path: ./ruleset/private-direct.yaml
url: https://example.invalid/rules/private-direct.yaml
interval: 86400
service-proxy:
type: http
behavior: classical
format: yaml
path: ./ruleset/service-proxy.yaml
url: https://example.invalid/rules/service-proxy.yaml
interval: 86400
rules:
- DOMAIN,router.local,DIRECT
- DOMAIN-SUFFIX,lan,DIRECT
- RULE-SET,private-direct,DIRECT
- RULE-SET,service-proxy,Websites Outside Mainland China
- GEOIP,CN,DIRECT
- MATCH,Websites Outside Mainland China
The domains in these examples use reserved test domains and are not real rule URLs ready for use. Replace them with rule sources you trust and can maintain. behavior: domain is for domain rules, keeping the file compact. classical supports classic rule syntax such as DOMAIN-SUFFIX, IP-CIDR and PROCESS-NAME, offering broader compatibility at the cost of a more complex parsing and matching structure. Choose the behavior type to match the remote file’s contents; changing only the field in the main configuration is not enough.
Order rules from narrow to broad
A clear order is usually: local exceptions, direct LAN access, services that explicitly require a proxy, services that explicitly require a direct connection, regional database rules, and finally MATCH. If a domain must override a public rule set, put the custom rule before that provider. Add no-resolve to IP rules when you want to avoid triggering DNS resolution during matching, but it is useful only when the connection already supplies an IP or an earlier step can provide one.
rules:
- DOMAIN,api.example.invalid,DIRECT
- DOMAIN-SUFFIX,example.invalid,Websites Outside Mainland China
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,Websites Outside Mainland China
The example first sends one host directly, then routes other domains under the same suffix through a proxy. This demonstrates the principle that “more specific rules come first.” Also watch for DOMAIN-KEYWORD, which can accidentally match unrelated domains containing the same text. When a suffix rule is sufficient, prefer DOMAIN-SUFFIX; use DOMAIN when you need exact control over a single host.
Rule Updates and Rollback
Rule-provider updates should not be treated as client upgrades. The client, core, subscription nodes and rule providers each change on their own schedule. Change one layer at a time, check the logs to confirm that providers loaded successfully, then test several representative domains. If many websites behave incorrectly after an update, restore the previous cached rules or temporarily disable the new provider instead of changing DNS, TUN and proxy groups at the same time. Keeping personal rules in a separate file prevents subscription refreshes from overwriting local changes.
When logs show a rule-provider download failure, first check whether the URL is reachable, the file format matches, and the cache directory is writable. If startup fails but a manual update succeeds later, the network may not have been ready when the device first came online. Increase the automatic update interval and keep a valid cache. Basic rule terminology is available in the quick reference. Do not judge results by rule names alone; the decisive evidence is the matched rule and proxy group shown in the connection log.
03 / Name Resolution
DNS Optimization and the Resolution Path
DNS configuration controls how domains become addresses and affects whether rules receive enough information to work. Problems are often mistaken for unavailable nodes: the node may be connected normally while DNS fails, returns unsuitable results or uses the wrong network path, all of which can make a website appear unreachable. Troubleshoot in three separate steps: who handles the DNS query, where it is sent, and how the result enters rule matching. Do not simply keep switching nodes.
Basic Listener and Upstream Roles
enable controls whether the mihomo DNS module is enabled, while listen sets its listening address. For local use, prefer a loopback address. Android clients generally manage the listener and VPN interception themselves, so there is no need to expose a port to LAN devices. default-nameserver mainly resolves the domains of encrypted DNS upstreams, so it is usually set to resolvers reachable by IP. nameserver handles normal queries, while proxy-server-nameserver can resolve proxy-server domains separately, preventing their resolution from depending on a proxy chain that has not been established yet.
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 1.1.1.1
- 8.8.8.8
nameserver:
- https://1.1.1.1/dns-query
- https://8.8.8.8/dns-query
proxy-server-nameserver:
- 1.1.1.1
- 8.8.8.8
Choose upstream addresses based on current network reachability; more is not always better. Parallel queries can return different results and make diagnosis harder. Start with a stable set of upstreams as a baseline, then add split resolution as needed. If the proxy server uses a domain name, ensure that name can resolve before the proxy starts; otherwise you create a loop where the proxy needs DNS and DNS needs the proxy.
redir-host vs. fake-ip
redir-host returns real resolved addresses, so connections behave more like the system’s normal flow and compatibility is straightforward. However, the core may see only an IP later, and whether domain rules work depends on the traffic entry point and mapping information. fake-ip assigns a temporary address from a reserved range to each domain. When an app connects to that address, the core restores the original domain from its mapping and applies the rules. This generally keeps domain rules consistent in TUN mode and reduces the chance that real DNS results are exposed to the app too early.
Fake-IP is not a remote server address and should not be mistaken for a resolution error. Results in the 198.18.0.0/16 range usually indicate that enhanced mode is working. What matters is whether the core has captured the connection and whether the corresponding mapping still exists. Some LAN discovery, device casting, connectivity checks and apps that depend on special DNS responses are unsuitable for Fake-IP; use a filter list to make those domains return real addresses.
dns:
enhanced-mode: fake-ip
fake-ip-filter:
- "*.lan"
- "*.local"
- "time.*.com"
- "+.stun.*.*"
- "connectivitycheck.gstatic.com"
Add filter entries gradually based on actual logs. Putting too many suffixes in the filter list weakens Fake-IP’s ability to identify domains; filtering too little can break LAN service discovery. After changes, clear the old DNS cache or restart the core so stale mappings do not affect the diagnosis.
Choose Resolvers by Domain
nameserver-policy lets specific domains or rule providers use designated resolvers. For example, send internal domains to the home router and public domains to encrypted DNS. Keep the policy one-way and easy to explain: an internal resolver should serve internal domains, not act as a random candidate for every query. When a mobile device switches between Wi-Fi and cellular data, a LAN resolver may suddenly become unreachable, so policies that depend on LAN addresses should account for this failure mode.
dns:
nameserver-policy:
"router.local": 192.168.1.1
"+.home.arpa": 192.168.1.1
"+.example.invalid":
- https://1.1.1.1/dns-query
Use a fixed DNS verification order: confirm that the domain generates a query log, confirm that the upstream returns a result, confirm the matched rule, and finally check that the connection uses the expected proxy group. If an IP address works but the domain does not, the problem is more likely in resolution. If the domain resolves and the log shows a connection failure, move on to the node, route or TUN instead of continuing to change DNS.
04 / Traffic Capture
TUN, Fake-IP and the Android VPN Interface
TUN mode receives system traffic through a virtual network interface, allowing apps that ignore system proxy settings to enter mihomo. Android clients create this interface using the system VPN permission, so a VPN indicator in the status bar is normal. TUN solves the traffic-entry problem; Fake-IP solves domain mapping and identification. They are often used together but are not the same feature.
Automatic and Strict Routing
auto-route lets the core configure routes automatically and direct target traffic to the TUN interface. strict-route further constrains paths that do not enter the interface as expected, reducing bypasses through other routes, but it can also intensify conflicts with hotspot sharing, LAN access, enterprise VPNs or special system routes. When enabling TUN for the first time, start with automatic routing, confirm basic access, then evaluate strict routing based on leak prevention and app compatibility needs.
tun:
enable: true
stack: mixed
auto-route: true
strict-route: false
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
stack selects the TUN network-stack implementation. mixed is generally used to balance compatibility and performance, but supported values can vary by system and client wrapper; follow the configuration accepted by the current client. Switching stacks is a diagnostic measure, not something to change repeatedly without evidence. auto-detect-interface identifies the actual outbound interface and is useful when a device moves between Wi-Fi and mobile data.
DNS Hijacking Scope
dns-hijack sends queries addressed to common DNS ports to the mihomo DNS module, making it harder for apps to bypass a unified resolution policy. It may not capture encrypted DNS built into an app, which appears as ordinary HTTPS or TLS traffic. If a browser enables Secure DNS independently, those lookups may not appear in mihomo’s regular DNS logs. To enforce one behavior, disable the app’s independent resolver or explicitly accept and diagnose the two resolution paths separately.
The hijacking scope should not be expanded without limit. LAN discovery, carrier captive portals and internal enterprise domains may depend on local DNS. If a captive portal does not appear after joining Wi-Fi or printer names stop resolving, first pause TUN to compare behavior. Then decide whether to use direct rules, real-IP filters or a LAN DNS policy instead of deleting all DNS configuration.
Per-App Routing on Android
An Android VPN interface can usually be held by only one app at a time. Other VPNs, work-profile management tools, VPN-based firewalls or filtering apps may conflict with Clash Plus, Clash Meta for Android, FlClash or Surfboard. If the interface says it has started but the system has not created a VPN interface, check whether another app still holds the permission and whether background-running permission has been revoked.
If the client supports per-app inclusion or exclusion, capture only selected apps or let a small number of LAN tools bypass the tunnel. Inclusion mode is useful for testing: start with one browser, confirm its path, then add other apps gradually. Exclusion mode suits setups where almost everything should be captured except banking apps or LAN controls. Combining both modes can be confusing, so choose one clear policy and note which apps connect directly through the system.
| Symptom | Check first | Verification step |
|---|---|---|
| All apps lose network access after startup | Default policy, DNS and TUN routes | Switch to a direct policy first, then compare with DNS hijacking disabled |
| Browser works, but some apps do not | Per-app routing, QUIC, certificates or network stack | Check whether connections from the app appear in the log |
| LAN devices are unreachable | Private subnet rules and strict routing | Confirm private subnets connect directly before broad proxy rules |
| Connection is lost after switching Wi-Fi | Actual outbound interface and system battery restrictions | Recreate the VPN interface and check automatic interface detection |
To understand how TUN works at a basic level, read How Clash TUN Mode Works on Android and How to Enable It. This chapter focuses more on how the parameters interact. Judge the result not by whether a switch appears enabled, but by whether the system VPN interface, DNS logs, connection logs and matched rules form a complete chain.
05 / Domain Recovery
Domain Sniffing: Uses, Coverage and Limits
Some connections enter the core with only a destination IP, leaving the rule system unaware of the original domain. Domain sniffing reads protocol metadata visible early in the connection, such as the server name in a TLS handshake or the host field in an HTTP request, then restores the domain for rule matching. It does not read webpage contents and cannot recover a domain from every encrypted connection. Results depend on whether the protocol exposes metadata and whether the connection is captured during the handshake.
TLS, HTTP and QUIC Sniffing
TLS sniffing commonly reads the SNI from ClientHello, HTTP sniffing reads Host, and QUIC sniffing handles related UDP-based handshakes. Enabling more protocols broadens coverage but also increases the chance of false detection and compatibility issues. Start by enabling only the ports you actually need and keep a skip list. If an app immediately retries, video startup fails or the logged domain does not match the service, disable sniffing for that domain or destination range rather than turning off the entire rule system.
sniffer:
enable: true
parse-pure-ip: true
force-dns-mapping: true
override-destination: false
sniff:
HTTP:
ports:
- 80
- 8080-8880
TLS:
ports:
- 443
- 8443
QUIC:
ports:
- 443
skip-domain:
- "+.lan"
- "+.local"
parse-pure-ip allows the core to try recovering a domain for a pure-IP destination. force-dns-mapping uses DNS mapping information to assist identification, especially with Fake-IP and when the core DNS already knows the domain mapping. override-destination controls whether the sniffed domain replaces the original destination for subsequent connections. Overriding can improve consistency for some domain rules, but may affect services that depend on a fixed IP, special certificate behavior or private protocols, so enable it only when the need is confirmed.
Combining Sniffing with Fake-IP
With Fake-IP, the core can usually obtain the original domain from the virtual-address mapping, so sniffing mainly supplements traffic that bypasses core DNS and connects directly to a real IP. In redir-host or some transparent-proxy setups, sniffing is more important for domain recovery. When both mechanisms are enabled, understand where the domain came from: a logged domain may come from DNS mapping or from the protocol handshake. If they differ, the override policy determines which name is ultimately used for rule matching and the connection.
Still matching an IP rule after adding domain rules does not necessarily mean sniffing failed. The connection may have no sniffable field, may use an encrypted client greeting extension, may have been processed by an IP rule before sniffing completed, or may use a custom protocol directly. Use a normal HTTPS website as a baseline, confirm that the log shows its SNI, and then test the problematic app. Do not disprove the entire feature with a protocol that does not support sniffing.
Skip Lists and Risk Control
skip-domain is suitable for LAN domains, device-discovery services and known business domains that behave incorrectly after sniffing. Some configurations also support skipping by destination or source address for internal networks. Keep skip rules as specific as possible and avoid overly broad suffixes. Skipping an entire common top-level domain effectively removes domain recovery from a large amount of public traffic.
Domain sniffing cannot replace correct DNS configuration. If DNS has already failed, the app may never create a connection that can be sniffed; when a connection uses an IP, sniffing is not guaranteed to recover the name. Stabilize the DNS and TUN paths first, then use sniffing to supplement pure-IP traffic. After each change, review the destination, sniffing result, matched rule and final proxy group in the logs; all four should agree with the intended behavior.
On mobile networks, UDP and QUIC may take a different path from TCP. If webpages open but video or real-time communications fail, temporarily disable QUIC sniffing or block UDP 443 with a rule as a comparison, allowing the app to fall back to TCP. This is for diagnosis and should not become a default block on all UDP. After confirming the service and network conditions, decide which protocol range to keep.
06 / Configuration Orchestration
Local Overrides and Multiple Subscription Merging
Subscriptions are usually maintained by service providers and may replace nodes, proxy groups or rules during refreshes. Direct edits to the generated main configuration are easily lost at the next update. The purpose of an override is to separate the frequently changing remote layer from the local settings you want to keep. Nodes can come from subscriptions, while DNS, TUN, personal rules and proxy-group structure remain controlled by local overrides.
Override Priority and a Minimal Change Surface
Clients implement overrides under different names, such as overrides, mixins, configuration patches or scripts. Whatever the label, first confirm the merge direction: do local fields replace remote fields, or are arrays appended to remote arrays? Mappings can usually be merged by key, while array fields may be replaced wholesale. Rules and proxy groups are arrays; assuming “append” when the client actually replaces them can make all rules from the subscription disappear.
The safest approach is to keep the override scope small. Change only fields that clearly need local control, such as the DNS enhanced mode, TUN switch, external-controller listener and personal exceptions at the top of the rules. If local configuration fully takes over proxy groups, also check whether remote rules refer to group names that no longer exist. Names are part of the reference relationship: changes to spaces, capitalization or full-width punctuation can make a target impossible to find.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
profile:
store-selected: true
store-fake-ip: true
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
store-selected preserves proxy-group selections so you do not have to choose them again after a subscription refresh or core restart. store-fake-ip can save Fake-IP mappings and reduce the impact of losing existing connection mappings after a restart. Enable these according to the client’s storage permissions and the observed behavior. If mappings become inconsistent, clear the cache and rebuild them instead of continually accumulating stale state.
Import Multiple Subscriptions through proxy-providers
Do not simply copy and paste multiple subscriptions into one huge proxy array. Using proxy-providers lets each source update and cache independently, then be referenced by proxy groups as needed. Give the primary and backup subscriptions different file paths so failed updates cannot overwrite one another. Health checks can run at the provider level, allowing multiple groups that reference the same provider to share the results.
proxy-providers:
provider-main:
type: http
url: https://example.invalid/subscription/main
path: ./providers/main.yaml
interval: 86400
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 600
provider-backup:
type: http
url: https://example.invalid/subscription/backup
path: ./providers/backup.yaml
interval: 86400
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 900
The example URL uses a reserved test domain. Real subscription URLs are sensitive configuration and should not appear in public files, screenshots or shared logs. Nodes from multiple sources may have duplicate names, which can lead the core or client to overwrite, rename or reject entries during merging. Use prefixes, suffixes or filters in providers to distinguish sources, such as adding a consistent “Backup” prefix to a secondary source. Then combine prefixes with regional keywords when filtering groups to avoid ambiguity.
Update Failures and Rollback Strategy
Subscription refresh intervals should not be excessively short. Node changes rarely require minute-level updates; frequent requests increase failure opportunities and may replace the active configuration with incomplete content during a temporary network outage. When a client offers a setting such as “Auto-update configuration · every 1,440 minutes,” a daily interval is generally enough for routine changes. After each update, validate the syntax before switching the running configuration. If the client supports previous versions, keep at least one known-good copy.
If merging multiple subscriptions prevents startup, split the configuration by layer: keep only the local base first, add the primary provider, then the backup provider, and finally restore proxy groups and rules. Parsing errors can often be narrowed to a field or line number; logical errors require checking whether nodes loaded, groups contain members and rule targets exist. Do not keep adding conversion scripts while the configuration is failing, as they bury the original error under more processing layers.
When moving between desktop and Android, migrate generic fields without device-specific paths first. Windows and Android handle file paths, listener permissions, TUN implementations and per-app routing differently, so do not assume one complete configuration can be reused unchanged on every platform. For migrating from discontinued clients, see Configuration Migration to a mihomo-Core Client.
07 / Control API
External Panels and API Security Scope
mihomo’s external control API lets compatible panels read proxy groups, switch members, and view connections and logs. It provides management capabilities, not a proxy port. Plan the control API separately from mixed-port, the HTTP proxy port and the SOCKS port. When used only on the device, bind it to a loopback address to reduce the chance that other LAN devices can access the control panel.
Listening Address and Access Token
external-controller: 127.0.0.1:9090
secret: "replace-with-a-local-password"
external-ui: ./ui
external-ui-name: dashboard
external-controller specifies the listening address and port. 127.0.0.1 accepts local connections only, which suits an embedded client panel or a browser on the same device. If LAN administration is genuinely required, bind to a LAN-reachable address, set an access token and restrict sources with the system firewall. The control API can change runtime state and expose connection details, so it should never be published directly to the internet.
external-ui points to the directory containing static panel files. The panel is only the front end for the control API; a successful load does not mean it has connected to the core. If the page is blank or proxy groups are missing, check separately that the static files exist, the browser can reach the control address, the token matches, and the panel’s protocol and port are correct. When the client includes a built-in panel entry, prefer its managed path to avoid differences in manually configured directories.
Access the LAN Control Panel from Another Device
Cross-device access requires four conditions: the core listens on a non-loopback address, the operating system firewall allows the port, the client device can reach the host’s LAN address, and the control token is correct. A failure at any layer appears as a panel connection error. First access the local address on the device running the core, then test from another device on the same LAN. Do not start by changing proxy ports, TUN routes and the control API, because each setting solves a different problem.
Enabling allow-lan mainly controls whether proxy ports accept LAN connections; it is not the sole switch for the external control API. The control API has its own listening address. If you want other devices to use the proxy without managing the core, expose the proxy port while keeping the control API bound to loopback. Conversely, exposing only the control API does not automatically give LAN devices proxy access.
Read Runtime Status through the API
During debugging, request the control API locally to confirm that the core responds. The examples below request only version information and the proxy-group list; they contain no real token. When authentication is configured, provide the corresponding authorization in the request header. Run the commands on the same device as the core.
curl http://127.0.0.1:9090/version
curl http://127.0.0.1:9090/proxies
The first request confirms that the control service is running; the second confirms that proxy groups loaded successfully. If the port refuses connections, check the listening address, port conflicts and core startup log first. An unauthorized response means the API exists but the token does not match. If data is returned but the panel remains blank, the issue is in the panel configuration, browser restrictions or static resources, not the proxy groups themselves.
Log Levels and Connection Monitoring
log-level: info is suitable for routine troubleshooting and shows rule matches and connection events. More verbose debug levels generate many records and should be enabled only briefly while reproducing a problem. Logs may contain domains, LAN addresses and proxy names; before sharing them, remove personal subscription URLs, authentication fields and unrelated connections. Restore the normal level when finished to avoid unnecessary storage pressure.
| API status | Meaning | Next step |
|---|---|---|
| Connection refused | Nothing is listening or the port is unreachable | Check the startup log, listening address and port conflicts |
| Unauthorized response | The control service is reachable, but the token is incorrect | Compare the access token in the panel and configuration |
| API returns data, but the panel is blank | The core is working; the front-end connection or resources have a problem | Check the panel address, static directory and browser console |
| Proxy group has no members | Provider, filter or group reference problem | Check provider update status and the filter results |
External panels are useful for observation but should not replace version control for the configuration files. Switching a proxy group is runtime state; rules, DNS and TUN parameters should still be changed in the configuration source. Otherwise, a restart, subscription refresh or client change will not preserve temporary panel actions or the complete intended setup.
08 / Troubleshooting
Configuration Diagnostics and Long-Term Maintenance
When a complex configuration fails, the most effective approach is to reduce variables rather than flip every switch in succession. Divide the path into seven layers: configuration parsing, proxy providers, DNS, rule matching, proxy selection, traffic capture and destination connection. Confirm one layer at a time. The first error in the log is usually more valuable than the cascade that follows; fix upstream issues such as an unreadable provider or configuration that will not load before investigating a specific website.
Start with the Smallest Working Configuration
Keep a minimal configuration as a diagnostic baseline with one working proxy, one manual proxy group, basic DNS and a final rule. Once it starts successfully, restore layers in order: proxy groups, rule providers, TUN, Fake-IP, sniffing and overrides. After each layer, test the same targets: one direct website, one website that should use a proxy, one LAN address and one problematic app. Fixed test targets prevent normal website fluctuations from being mistaken for configuration changes.
mixed-port: 7890
mode: rule
log-level: info
proxies:
- name: local-test
type: socks5
server: 127.0.0.1
port: 1080
proxy-groups:
- name: Test Policy
type: select
proxies:
- local-test
- DIRECT
rules:
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,Test Policy
The local SOCKS service in the example works only when the device is actually running that port. It demonstrates the minimal structure and is not a public node. For diagnosis, replace it with a subscription node that has been confirmed to work. The purpose of a minimal configuration is to prove that the client, core and basic network path function; if it still will not start, check YAML indentation, supported fields and port conflicts first.
Choose the Diagnostic Layer from the Symptom
For “connected but no internet,” first check whether the default policy selected a working member, then whether DNS returns a result, and finally whether TUN has captured the traffic. See the Android step-by-step troubleshooting checklist for a complete list. “Only some websites fail” is more likely related to rules, IPv6, DNS results, UDP or destination-side exit restrictions. For “all nodes are slow,” first rule out local Wi-Fi, cellular service and system battery restrictions; if only one node is slow, focus on that node and route. For speed issues, continue with the three-layer method for diagnosing nodes, routes and local settings.
If the log shows DIRECT when a proxy was expected, check rule order and whether the domain was successfully recovered. If the correct proxy group is shown but the connection fails, inspect its current members. If there are no connection logs, check whether the app entered the system proxy or TUN. DNS logs without a subsequent connection may indicate app caching, unsuitable resolution results or a system-level block. Each symptom belongs to a different layer; do not handle every problem by simply switching nodes.
YAML Structure and Common Parsing Errors
YAML uses spaces for nesting and must not mix in tabs. List-item hyphens should align with entries at the same level; names containing colons, hash signs or special characters can be quoted. Duplicate keys may be overwritten by the parser or cause an error. When merging configurations, check especially for two dns sections, two rules sections or multiple providers with the same name. A configuration that parses successfully can still contain broken references, so verify proxy groups, rule providers and provider names.
When an error reports a line number, inspect the preceding lines as well. Missing indentation or a closing quote is often located before the reported line. Remove the most recently added complete block to see whether the configuration recovers, then add it back in halves to locate the problem by binary search. Do not delete only the reported line; it may simply be the first point where the parser can no longer continue.
Change Logs, Backups and Update Cadence
Keep three states: the last confirmed working configuration, the current test configuration and a snapshot from before a subscription or rule update. Use dates and purposes in filenames, but never store subscription URLs in public locations. For every change, record why it was made, which fields changed and how it was verified; this is easier to roll back than keeping a large collection of unexplained copies. Run client upgrades, core changes, subscription updates and rule-provider updates separately so one change does not affect all four layers at once.
When updating a client, choose a package that is still maintained and suits the current platform. On Android, see the Android section of the installation packages page for Clash Plus, Clash Meta for Android, FlClash and Surfboard; choose the corresponding package for desktop platforms. Clash for Windows and ClashX Meta are no longer maintained. When migrating, export the portable configuration first, then handle platform-specific fields instead of continuing to build patches around an old client.
Recommended Troubleshooting Workflow
- Confirm that the configuration loaded. Check the startup log for syntax errors, unsupported fields or port conflicts.
- Confirm that nodes and providers exist. Every proxy group needs members, and remote providers should have a usable cache.
- Confirm that DNS returns a result. Distinguish between a query that was never sent, an upstream failure and an unsuitable result.
- Confirm the rule match. Use the log to verify the domain, rule type, target proxy group and current member.
- Confirm the traffic entry point. At least one of the system proxy, TUN or per-app routing must cover the problematic app.
- Confirm the destination connection. Only then assess the node route, destination restrictions, UDP or IPv6 path.
Stable long-term configurations are usually not complex. They have a clear proxy strategy, a limited set of trusted rule sources, an explainable DNS path, a controlled TUN scope and reversible overrides. Automation should come only after these relationships are clear. The goal is not to enable every option, but to make the entry point, name resolution, rule match and exit selection for every connection explainable from the logs.