Clash Rules Explained: DOMAIN-SUFFIX, IP-CIDR, Match Order, and MATCH Fallback
Clash rules are evaluated from top to bottom, stopping at the first match. Learn the syntax for DOMAIN, DOMAIN-SUFFIX, DOMAIN-KEYWORD, IP-CIDR, GEOIP, and MATCH, plus how no-resolve works and how to order rules.
Rules not working? First check that traffic is using Rule mode
You added a direct-connection rule for a site, but it still uses a proxy. You changed an IP range to use a proxy, but nothing changed. These issues aren't always caused by invalid syntax. First make sure the app's traffic passes through Clash, then confirm the core is in Rule mode, and only then inspect the rules.
- In the client's Proxy Mode settings, select Rule. Some clients call this Rule mode. Don't test routing rules in Global or Direct mode.
- Open the Connections page and visit the target site again. If no new connection appears, check the system proxy, the app's own proxy settings, or which traffic TUN is capturing.
- Make sure the selected profile is the one you just edited. After saving the file, reload the profile in the client; saving alone may not update the running core.
- Close existing connections from the target app before testing again. Rules select an outbound when a connection is established; existing long-lived connections aren't automatically rerouted when the file changes.
Rule structure: type, match value, and outbound policy
Rules are usually listed under the YAML rules: key, with each entry starting with a hyphen. A domain rule typically has three fields: rule type, match value, and outbound policy. MATCH takes no match value; IP rules that support no-resolve can have a fourth field.
rules:
- DOMAIN,login.example.com,DIRECT
- DOMAIN-SUFFIX,example.org,REJECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,DIRECT
This example uses built-in policies to make the structure easy to follow: DIRECT connects directly, and REJECT blocks the connection. For actual proxying, the last field must be the name of a proxy node or policy group already defined in your profile. PROXY is not a universal built-in policy available in every profile. Copying it without a node or group by that name may cause the profile to fail to load.
- Use English commas, not full-width Chinese commas.
- Use spaces for YAML indentation, never tabs. Keep rules at the same indentation level within a list.
- Policy names must exactly match their definitions, including capitalization, spaces, and symbols.
- When editing an existing profile, add entries under its existing
rules:key. Don't add another top-level key with the same name.
Domain rules: DOMAIN, DOMAIN-SUFFIX, and DOMAIN-KEYWORD
| Type | Example | What it matches |
|---|---|---|
DOMAIN | DOMAIN,example.com,DIRECT | Matches only example.com, not www.example.com. |
DOMAIN-SUFFIX | DOMAIN-SUFFIX,example.com,DIRECT | Matches example.com and its subdomains, such as www.example.com and api.example.com. |
DOMAIN-KEYWORD | DOMAIN-KEYWORD,example,REJECT | Matches connections whose domain contains the string example; this is broader than a suffix rule. |
Suffix matching respects domain boundaries; it doesn't match any string that happens to end the same way
DOMAIN-SUFFIX,example.com,DIRECT matches a.example.com, but not notexample.com or example.com.other.org. You generally don't need to write *.example.com; the suffix rule already includes subdomains.
Use only the domain in the rule value; don't include https://, a port, or a path. For https://example.com:8443/account, the domain is still example.com. Standard domain rules can't distinguish between paths such as /account and /video on the same site.
Put exact exceptions before broader rules
rules:
- DOMAIN,login.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,REJECT
- MATCH,DIRECT
Here, login.example.com connects directly, while other domains under example.com are rejected. If you swap the first two lines, the login domain will match the suffix rule first, leaving the exact rule no chance to take effect. The core doesn't rank rules by specificity or keep looking for a better match.
Use DOMAIN-KEYWORD only when you know exactly what it may match. Don't use a common short word to route an entire category of services. The shorter the keyword, the more likely it is to catch unrelated domains that happen to contain the same string.
IP-CIDR and GEOIP: IP ranges aren't the same as geographic databases
IP-CIDR checks whether a destination IPv4 address falls within a specified range. 192.168.0.0/16 covers 192.168.0.0 through 192.168.255.255; /32 represents a single IPv4 address. Use IP-CIDR6 for IPv6 ranges and /128 for a single IPv6 address.
rules:
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,Proxy Selection
GEOIP,CN,DIRECT checks whether the destination IP belongs to CN according to the currently loaded IP geolocation database, then connects directly. It doesn't mean "connect to all Chinese-language sites directly," and it doesn't classify traffic by page language or domain suffix. CDN address allocation, database updates, and differences in IPv4 and IPv6 responses can cause the same site to match differently across networks.
For a service that must consistently use a specific policy, prefer an explicit domain rule. Geographic rules are easier to maintain as a later fallback. If the required geolocation database won't load, check the client's resource-loading errors in the logs rather than trying to hide the problem by changing rule order.
What no-resolve does: prevents this rule from triggering an extra domain lookup
When a connection provides a domain but a rule needs the destination IP, the core may perform a DNS lookup to evaluate the IP match. no-resolve prevents this IP rule from actively triggering a domain lookup. It isn't a global DNS switch, and it doesn't mean "ignore this IP rule."
- The destination is already an IP: The rule can check whether the address falls within the range, and may still match even with
no-resolve. - The connection already has a usable destination IP: The rule may still be evaluated. This parameter doesn't mean "always skip domain-based connections."
- Only a domain is available, with no usable destination IP: The rule won't trigger an extra lookup just to evaluate itself, so the core may continue to later rules.
rules:
- DOMAIN-SUFFIX,example.com,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,Proxy Selection
This order handles explicit domains first, checks private IP ranges next, and then evaluates the geographic rule. Note that although the second rule uses no-resolve, the third doesn't, and may still trigger a lookup needed for GEOIP matching. Adding the parameter to one rule doesn't control DNS behavior for every rule after it.
If you change the third rule to GEOIP,CN,DIRECT,no-resolve, a connection with only a domain and no usable destination IP may not be eligible for geographic matching here, and could fall through to the proxy fallback. Whether to add the parameter depends on your routing goals and DNS path; don't apply it everywhere just to reduce lookups.
MATCH fallback and the top-to-bottom rule order
MATCH matches unconditionally and uses the format MATCH,policy-name. It's usually placed at the end of the rule list to catch connections not handled by any earlier rule. Don't write MATCH,*,policy-name, or place it before rules that still need to be evaluated.
rules:
- DOMAIN,login.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,Proxy Selection
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,Proxy Selection
Check this order with three visits
- Visit
login.example.com: the first rule matches, so rule evaluation stops and the connection usesDIRECT. - Visit
static.example.com: the first rule doesn't match, so the second does and sends the connection to the "Proxy Selection" policy group. - Visit a service outside the domains above whose destination IP doesn't match any IP or GEOIP rule: the final
MATCHsends it to "Proxy Selection".
These outcomes follow from the example configuration; they don't mean the example domains host accessible services. Test with real destinations you want to route. Also, matching a policy group doesn't guarantee traffic will use a remote proxy node: if that group currently selects DIRECT, the connection will still go direct.
A practical order is: exact exceptions, explicit domain scopes, other service-specific rules or rule sets, IP and geographic fallbacks, then the final fallback. The core doesn't require this order; if a reject rule must take priority over an exception, move it above that exception. The key is to understand which later rules each entry covers, not to sort mechanically by rule type.
Subscriptions and rule sets: get the content and placement right
If custom rules disappear after a subscription update, you may have edited a subscription file that gets overwritten on download. Keep a copy of the original profile, then use the client's override, merge, or extension features. Client interfaces and merge formats vary; don't assume an extension field from one client is a universal Clash core setting.
RULE-SET placement matters too
In supported versions of the Clash core and in mihomo, rule providers are generally defined under rule-providers: and referenced with RULE-SET,provider-name,policy-name. These entries follow the same top-to-bottom evaluation order: if a broader domain rule matches first, later rule sets won't be checked.
- Use a domain-list format for
behavior: domainpayloads; don't put complete three-field outbound rules in them. - The payload for
behavior: ipcidris a list of IP ranges, suitable for address-range collections. behavior: classicaluses rule-condition syntax. The outbound policy is set by theRULE-SETentry that references it.
Rule types and extension fields vary across the original Clash, older forks, and mihomo. If you see an error such as unsupported rule type, check the client's About page or core information to identify the core actually in use, then consult its documentation. Updating the client interface doesn't necessarily update the core.
Test rules one change at a time; check the matched rule and final outbound
- Back up and save. Keep a copy of a profile that starts successfully. Add just one exact domain rule, reload the profile, and check for parsing errors.
- Close existing connections. Quit the target app or end its connection from the client's Connections page, then make a new request. HTTP/2 and HTTP/3 connection reuse in browsers may keep an old route active.
- Check the destination. In the connection details, review the domain, destination IP, matched rule, and policy chain. Field names vary between clients; don't rely on the overall traffic graph alone.
- Check the logs. If needed, temporarily set
log-leveltodebug, reproduce the issue once, then restoreinfo. Before sharing logs, redact subscription links, tokens, and any addresses you don't want made public.
| Symptom | Check first |
|---|---|
| Always matches MATCH | Is the rule loaded? Is the domain misspelled? Does the connection provide only an IP? Did the rule set load successfully? |
| Exact rule doesn't match | Is there an earlier suffix rule, keyword rule, or rule set that matches first? Was the test connection established before the change? |
| Matches a proxy group but still connects directly | Does the policy group currently select DIRECT? What is the final selection in any nested groups? |
| Domain rule doesn't work for some apps | Does the connection lack a domain? Does the app resolve names itself? Is the app actually covered by the system proxy or TUN? |
| Subscription update restores the old configuration | Did you edit the original subscription file or a persistent override? Were custom entries merged after broader rules? |
If traffic provides only the destination IP, a domain rule may have no basis for matching. mihomo's Fake-IP mapping, DNS interception, and sniffing settings affect whether domain information is available, but sniffing can't identify every protocol or recover the true domain from every encrypted connection. Check the connection details before adjusting DNS or sniffing, and avoid changing several things at once.