Understand How Clash Processes Rules First
Clash, Clash Meta, and the later mihomo core all pass connection details to the rules module. It reads the destination domain, destination IP, port, network type, and process information, then chooses a proxy group, a specific node, DIRECT, or REJECT. The key factor is not the number of rules, but their order.
Rules are checked one by one from top to bottom. Once the first matching rule is found, later rules are no longer considered for that connection. Put narrow, clearly scoped rules first, broader rules later, and use MATCH at the end for connections that match nothing else.
rules:
- DOMAIN,api.example.com,Development API
- DOMAIN-SUFFIX,example.com,Outside-China websites
- GEOSITE,cn,DIRECT
- GEOIP,CN,DIRECT,no-resolve
- MATCH,Default proxy
In this configuration, a request to api.example.com matches the first rule and uses the “Development API” policy group. Even though it also matches the second rule, DOMAIN-SUFFIX,example.com, that rule is never evaluated. A request to www.example.com skips the first rule and matches the second.
What Fields Does a Rule Usually Contain?
Common rules use comma-separated fields. The basic structure is “rule type, match target, policy.” Some rules accept an additional parameter at the end, such as no-resolve.
Rule type, match target, policy
IP-CIDR,203.0.113.0/24,Node selection,no-resolve
- Rule type: Specifies whether matching is based on a domain, IP address, port, process, or rule set.
- Match target: The specific domain, network range, port range, process name, or rule-set name.
- Policy: Must match an existing proxy group or node name in the configuration, or use a built-in action such as DIRECT or REJECT.
- Additional parameters: Control the matching process, for example by preventing an IP rule from resolving a domain solely to obtain its destination IP.
Policy names are case-sensitive, and names in rules must exactly match the name under proxy-groups. If the configuration defines “Node selection” but the rule uses “Node selection ” or “Proxy selection,” the configuration may fail to load or the policy may not be found.
How to Choose Between DOMAIN, DOMAIN-SUFFIX, and DOMAIN-KEYWORD
Domain rules are ideal for routing websites and APIs. They use the hostname in the connection directly, without depending on which IP the destination server currently resolves to. For services behind a CDN, frequently changing addresses, or multiple network ranges, domain rules are usually more reliable than fixed IP rules.
DOMAIN: Match One Exact Domain
rules:
- DOMAIN,login.example.com,Login service
- DOMAIN,cdn.example.net,Static assets
DOMAIN requires an exact hostname match. The first rule matches login.example.com, but not www.example.com, api.login.example.com, or the root domain example.com. It is suitable for a single API, login host, download host, or other clearly bounded destination.
DOMAIN-SUFFIX: Match a Root Domain and Its Subdomains
rules:
- DOMAIN-SUFFIX,example.com,Outside-China websites
- DOMAIN-SUFFIX,example.org,DIRECT
DOMAIN-SUFFIX,example.com covers example.com, www.example.com, and a.b.example.com. There is no need to add an asterisk, and it should not be written as *.example.com. If a site’s pages, images, and APIs use different subdomains under one primary domain, DOMAIN-SUFFIX is the simpler choice.
DOMAIN-KEYWORD: Match a String Anywhere in the Domain
rules:
- DOMAIN-KEYWORD,example,Test policy
This rule matches connections whose domain contains example; the string does not have to appear at the end. Besides example.com, it may also match example-cdn.net and notexample.org. Because its scope is broad and can include unrelated domains, place it after exact rules and choose a sufficiently distinctive keyword.
| Rule | Best for | Key limitation |
|---|---|---|
| DOMAIN | A single API, login host, or download host | Does not include other subdomains |
| DOMAIN-SUFFIX | An entire primary domain and all subdomains | May cover different services under the same domain |
| DOMAIN-KEYWORD | A changing domain structure with a stable keyword | Higher risk of unintended matches |
IP-CIDR, IP-CIDR6, and What no-resolve Does
IP-CIDR matches IPv4 addresses and ranges, while IP-CIDR6 is for IPv6. The CIDR suffix indicates the network prefix length: /32 represents one IPv4 address, /24 usually covers 256 consecutive IPv4 addresses, and IPv6 /128 represents one address.
rules:
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,203.0.113.8/32,Dedicated node,no-resolve
- IP-CIDR6,2001:db8::/32,Dedicated node,no-resolve
The first two rules are commonly used for direct access to private networks. The third matches only one IPv4 address. The example ranges 203.0.113.0/24 and 2001:db8::/32 are documentation addresses and should not be used as real service networks.
no-resolve Does Not Mean “Do Not Use DNS”
When a connection contains only a domain name, an IP rule needs the destination IP to evaluate a match. Without no-resolve, the core may trigger a DNS lookup solely for rule matching. With no-resolve, the IP rule will not proactively resolve the domain just to test the rule; if the connection already provides a destination IP, it can still match normally.
- DOMAIN-SUFFIX,example.com,Outside-China websites
- IP-CIDR,203.0.113.0/24,Dedicated node,no-resolve
- GEOIP,CN,DIRECT,no-resolve
- MATCH,Default proxy
This order first uses the available domain information, then checks known IP addresses, and finally applies a fallback. It can reduce latency and DNS dependency caused by extra resolution during rule evaluation. Note that no-resolve does not disable Clash’s DNS module or change DNS requests made by the application itself.
GEOIP vs. Fixed Network Ranges
GEOIP,CN,DIRECT uses a GeoIP database to determine the region associated with the destination IP. It is useful for broad regional routing, but database classification is not the same as service ownership: an overseas brand may use a mainland-China CDN, while a service based in mainland China may connect to nodes outside China. For important services, put DOMAIN or DOMAIN-SUFFIX first and use GEOIP later for broad regional matching.
How GEOSITE, GEOIP, and Rule Sets Work Together
mihomo supports GEOSITE rules. GEOSITE data organizes domains into categories such as regions, services, and use cases. This avoids writing large numbers of DOMAIN-SUFFIX entries by hand, but available categories depend on the geosite data file bundled with or downloaded by the client.
rules:
- GEOSITE,category-ads-all,REJECT
- GEOSITE,private,DIRECT
- GEOSITE,cn,DIRECT
- GEOIP,private,DIRECT,no-resolve
- GEOIP,CN,DIRECT,no-resolve
- MATCH,Node selection
The order above handles ad domains first, then private domains and mainland-China domains, followed by known private and mainland-China IP addresses. Unmatched connections go to “Node selection.” If GEOSITE,cn,DIRECT is placed before a custom proxy-domain rule, that domain will connect directly as soon as it is included in the cn category.
Rule Sets Enter the Execution Queue Through RULE-SET
rule-providers defines a rule set’s source, format, update interval, and local storage path. RULE-SET determines where that set appears in the main rule queue. Declaring a provider does not make it run automatically; it must still be referenced under rules.
rule-providers:
direct-sites:
type: http
behavior: domain
format: yaml
path: ./ruleset/direct-sites.yaml
url: https://rules.example.net/direct-sites.yaml
interval: 86400
service-rules:
type: http
behavior: classical
format: yaml
path: ./ruleset/service-rules.yaml
url: https://rules.example.net/service-rules.yaml
interval: 86400
rules:
- DOMAIN,api.example.com,Dedicated node
- RULE-SET,service-rules,Node selection
- RULE-SET,direct-sites,DIRECT
- GEOIP,CN,DIRECT,no-resolve
- MATCH,Node selection
interval: 86400 checks for updates every 86,400 seconds, or 24 hours. behavior: domain should contain domain entries; behavior: ipcidr is for network ranges; and behavior: classical can contain classic rules with types. The provider format must match the actual file contents.
payload:
- example.com
- api.example.net
- +.service.example.org
This is a common YAML structure for a rule set with domain behavior. With classical behavior, entries usually include a rule type, such as DOMAIN-SUFFIX,example.com or IP-CIDR,203.0.113.0/24,no-resolve. Policies are not added to each provider entry; the main configuration assigns one with RULE-SET,rule-set-name,policy.
MATCH Fallbacks and Common Ordering Mistakes
MATCH has no match target, so every connection that reaches it will match. It should therefore normally be the last rule. It determines where otherwise uncategorized traffic goes. A manually switchable proxy group is often preferable to a fixed node, making it easier to adapt when a node is unavailable.
proxy-groups:
- name: Node selection
type: select
proxies:
- Automatic selection
- DIRECT
rules:
- DOMAIN-SUFFIX,intranet.example,DIRECT
- GEOSITE,cn,DIRECT
- GEOIP,CN,DIRECT,no-resolve
- MATCH,Node selection
Mistake 1: Putting MATCH Too Early
rules:
- MATCH,Node selection
- DOMAIN-SUFFIX,intranet.example,DIRECT
The second rule will never get a chance to run. Every connection is matched by the first rule. The configuration may still load, but all traffic will appear to use the same policy.
Mistake 2: Letting a Broad Suffix Override an Exact Exception
rules:
- DOMAIN-SUFFIX,example.com,DIRECT
- DOMAIN,video.example.com,Media node
video.example.com matches both rules, but it is taken by the first one. The correct approach is to move the exact exception above it:
rules:
- DOMAIN,video.example.com,Media node
- DOMAIN-SUFFIX,example.com,DIRECT
Mistake 3: Mismatched Policy and Proxy-Group Names
The “Node selection” policy in the rule must already be defined under proxy-groups. If the proxy group is actually named “Proxy selection,” the configuration will typically report that the policy cannot be found. Check the wording, spaces, and capitalization character by character.
Mistake 4: Treating a Port as a Service Identity
DST-PORT,443,Node selection matches every connection whose destination port is 443, not just one website. Modern HTTPS, application APIs, and some encrypted DNS services all use 443. Port rules are suitable for clear protocol boundaries, not as replacements for domain rules.
rules:
- DST-PORT,22,Development network
- NETWORK,udp,UDP policy
- MATCH,Node selection
Even port 22 may serve a non-SSH service, while SSH can run on another port. For work networks, combine the destination domain, network range, and port rather than relying on one field alone.
A Maintainable Rule-Ordering Template
There is no single correct order for every configuration, but a useful structure is “local exceptions, exact services, domain groups, IP and regional matches, default policy.” The template below suits common desktop setups; replace the names with proxy groups that already exist in the configuration.
rules:
# 1. Local networks and explicit exceptions
- DOMAIN,router.lan,DIRECT
- DOMAIN-SUFFIX,home.arpa,DIRECT
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
# 2. Exact policy for an individual service
- DOMAIN,api.example.com,Dedicated node
- DOMAIN-SUFFIX,example.net,Media node
# 3. External rule sets
- RULE-SET,work-services,Work network
- RULE-SET,streaming-services,Media node
- RULE-SET,direct-sites,DIRECT
# 4. Broad domain and regional matches
- GEOSITE,private,DIRECT
- GEOSITE,cn,DIRECT
- GEOIP,private,DIRECT,no-resolve
- GEOIP,CN,DIRECT,no-resolve
# 5. Final fallback
- MATCH,Node selection
Private IPv4 ranges include 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. The loopback range 127.0.0.0/8 should usually also go DIRECT. Whether to add these rules explicitly depends on the private-network rule sets and client settings already in place; duplicate rules do not improve matching.
Keep Rule Counts and Update Boundaries Under Control
- For a small number of fixed domains, write DOMAIN or DOMAIN-SUFFIX rules directly for the clearest troubleshooting.
- When similar entries grow into the dozens or hundreds, use a rule-provider so they can be updated separately.
- Avoid excessively short rule-set update intervals. For a static domain list, 86,400 seconds is usually sufficient.
- Keep important exceptions near the top of the main configuration so a remote rule-set update cannot change their priority.
- Do not add multiple regional rule sets with heavily overlapping purposes; otherwise it becomes difficult to tell which one actually matched.
How to Verify That a Configuration Change Works
After editing YAML, first confirm that the configuration can reload successfully. Desktop clients usually provide configuration editing and reload controls. Open the active configuration in the configuration manager, edit and save the file, then choose “Reload” or switch to that configuration. Menu names vary by client, but saving the file without reloading is not enough.
When using mihomo’s external controller, a common listen address is 127.0.0.1:9090; a common HTTP and SOCKS mixed port is 7890, and a common DNS listen port is 1053. These are only common defaults; follow the values in external-controller, mixed-port, and dns.listen in the active configuration.
Check Match Results in Four Steps
- Reload the configuration: Confirm that the client reports no YAML indentation errors, unknown rule types, or missing policies.
- Clear existing connections: Close the target application’s current connections and reopen it if necessary. Established long-lived connections will not be rerouted automatically when a new rule is added.
- Run a single test: Visit only one target domain to reduce interference from background synchronization, updates, and push connections.
- Inspect connection details: In the client’s “Connections” page, check the Host, destination IP, matched rule, and proxy chain.
Suppose you add DOMAIN,api.example.com,Dedicated node, but connection details show a match on DOMAIN-SUFFIX,example.com. First check that the exact rule really appears before the suffix rule. If the match is IP-CIDR, the application may be connecting directly to an IP, or the domain information may not have reached the core.
TUN Mode Follows the Same Rule Order
TUN mode changes how traffic enters the core; it does not turn rule matching into a parallel process. System proxy mode generally covers applications that honor proxy settings, while TUN mode can take over more TCP, UDP, and non-proxy-aware applications. Once traffic enters the core, it is still checked from the first rule downward.
When Fake-IP DNS enhanced mode is enabled, an application may first receive a reserved address, and the core uses the mapping to recover the domain for rule evaluation. Seeing a Fake-IP address on the Connections page does not mean DOMAIN rules have failed. If an application connects only to hard-coded IPs, handle it with IP-CIDR, GEOIP, or process rules.
Troubleshooting Order When Rules Do Not Work
Investigate rule problems across four layers: configuration loading, traffic entry, connection information, and rule position. Confirm that the core is using the new configuration, then determine whether the target traffic reaches Clash, and only then inspect the rules. Repeatedly changing syntax can obscure problems such as a disabled system proxy or a configuration that was never reloaded.
Can the Configuration Load?
- Check that YAML uses consistent indentation and that list items have a
-prefix. - Check that the policy name exists and that no leading or trailing spaces were added accidentally.
- Check that the current core supports the rule types used, such as GEOSITE, which depends on mihomo support and the corresponding data.
- Check that the rule-provider’s behavior, format, and actual file structure are consistent.
Does the Target Traffic Reach the Core?
In system proxy mode, an application may ignore system proxy settings; in TUN mode, route exclusions, interface conflicts, or permission issues may also interfere. If the target application is completely absent from the connection list, check the traffic entry point first instead of changing rules again. Existing browser connections may continue through connection reuse, so closing a tab may not immediately terminate the underlying connection.
Does the Core Receive a Domain or an IP?
DOMAIN rules require domain information. If an application connects directly to an IP, matching must rely on IP-CIDR, GEOIP, port, network type, or process information. Conversely, adding no-resolve to IP-CIDR makes the rule skip a connection that currently has only a domain name rather than resolving it and comparing the result.
Is There Already a Broader Rule Above It?
Above the target rule, look in order for DOMAIN-SUFFIX, DOMAIN-KEYWORD, RULE-SET, GEOSITE, GEOIP, and MATCH. Any earlier match prevents the target rule from running. For testing, temporarily move the exact rule to the top of the list; once confirmed, return it to a logically structured position.
Practical Conclusions for Writing Rules
- Clash evaluates rules from top to bottom and stops immediately after the first match.
- Use DOMAIN for one exact hostname, DOMAIN-SUFFIX for a root domain and its subdomains, and DOMAIN-KEYWORD with caution.
- IP-CIDR and IP-CIDR6 match addresses and network ranges; for fixed services, stable domains are usually the better choice.
no-resolveprevents an IP rule from proactively resolving a domain for matching; it does not disable DNS.- GEOSITE handles domain categories, while GEOIP handles IP regions; their data dimensions are different.
- rule-provider supplies the content, while the RULE-SET position in the main rule list determines execution priority.
- MATCH catches every remaining connection and should be placed at the end of the rule list.
- After making changes, reload the configuration, create a new connection, and inspect the actual matched rule and proxy chain.
A maintainable rule set does not depend on a huge number of entries. Each rule should have an explainable scope and position. Put exact exceptions first, then bulk rule sets, followed by regional matches and a MATCH fallback; when behavior differs from expectations, the execution order provides a fast path to the cause.