2026-07-15 Advanced 9 min read

Clash Custom Rule Syntax and Match Priority Explained

Breaks down DOMAIN, DOMAIN-SUFFIX, IP-CIDR, GEOIP rule syntax and match order, explains the top-down first-match-wins principle, and gives ordering tips to avoid rule conflicts.

Rules are the core mechanism in a Clash config that decide "which proxy this connection should use." Many people, the first time they edit a config file themselves, just pile rules together in whatever order and then find some rule that's clearly written correctly never seems to take effect — almost always because of a match-order problem. This note breaks down syntax by rule type, explains how the matching engine works top-down with first-match-wins, and gives a practical ordering approach to help you avoid rules overriding each other in a custom setup.

Basic structure and execution model

The rules section in a Clash config is a list, with each line being one rule in a consistent three-part format:

RULE-TYPE,VALUE,PROXY

The first field is the rule type, the second is the match value (some types skip this, like MATCH), and the third is the proxy or proxy group used once matched. The most important thing to understand about this system: Clash checks each new connection against the rule list from top to bottom, and as soon as a rule matches, it immediately uses that proxy and stops checking further rules. Even if later rules in the list would also match, they're never evaluated.

This "first-match-wins" principle means the order of rules is itself part of the logic, not just formatting. Keep this in mind while writing rules: rules placed higher have higher priority, so specific exceptions should sit above general catch-all rules, and broad, fallback-style rules should go last.

The end of a rule list usually includes a MATCH,PROXY line as the catch-all for any connection that didn't match earlier rules. This line must be the last line in the entire list — otherwise any rules after it will never run.

Common rule types, one by one

Below, from most to least frequently used, are the syntax and matching logic for the most common rule types.

DOMAIN: exact domain match

DOMAIN only matches a fully identical domain, with no fuzzy matching or subdomain expansion.

DOMAIN,ads.example.com,REJECT
DOMAIN,api.example.com,Proxy

The first rule above only blocks the exact address ads.example.com — something like cdn.ads.example.com or example.com won't match it. Good for precisely blocking or allowing one specific endpoint.

DOMAIN-SUFFIX: domain suffix match

DOMAIN-SUFFIX matches a given suffix plus all its subdomains, and is the type most commonly used in day-to-day routing rules.

DOMAIN-SUFFIX,youtube.com,Proxy
DOMAIN-SUFFIX,cn,DIRECT

The first rule matches youtube.com, www.youtube.com, music.youtube.com, and any other domain ending in that suffix. The second sends every domain ending in .cn straight through with no proxy. This type has broad coverage and is usually the first one people reach for when writing custom rules.

DOMAIN-KEYWORD: domain keyword match

DOMAIN-KEYWORD matches whenever the domain string contains the given keyword anywhere, regardless of position.

DOMAIN-KEYWORD,google,Proxy

This rule matches www.google.com, but also googleapis.com, googlevideo.com, and anything else containing the string google. This type has the widest match range, so watch for collateral matches — a keyword like ad could accidentally catch a lot of unrelated sites that just happen to contain those letters. Prefer a fuller keyword or switch to DOMAIN-SUFFIX where possible.

IP-CIDR and IP-CIDR6: matching by IP range

IP-CIDR uses CIDR notation to match a block of IPv4 addresses; IP-CIDR6 is the IPv6 equivalent.

IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
IP-CIDR,10.0.0.0/8,DIRECT,no-resolve

These two are commonly used to allow local network traffic through directly, so access to routers, NAS devices, and other LAN gear skips the proxy. The no-resolve parameter at the end matters: it tells Clash not to attempt reverse DNS resolution for this rule and just judge by the target IP directly, avoiding unnecessary resolution overhead for domain-based rules and preventing some edge-case mismatches.

Note that IP-based rules only apply when the connection's target is already an IP; if the connection was initiated by domain name and Clash hasn't resolved the target IP yet, these rules typically won't match at the domain stage — matching only happens once DNS resolution completes, which is why many people recommend putting domain-based rules earlier in the list.

GEOIP: matching by country/region IP database

GEOIP checks which country or region a target IP belongs to, using a built-in or externally loaded geolocation database.

GEOIP,CN,DIRECT
GEOIP,JP,Proxy

The first rule sends any IP identified as belonging to mainland China straight through; the second sends IPs identified as Japan through a proxy group named Proxy. GEOIP rules depend on a geo database that gets updated periodically, so a handful of edge-case IP ranges may occasionally show stale attribution — when you spot an obvious misclassification, pair it with a specific IP-CIDR rule to correct it.

GEOSITE: matching by domain category set

GEOSITE (supported by some cores, such as mihomo) uses pre-categorized domain rule sets, so one rule can cover a huge number of domains under a category — streaming services, social platforms, and so on — instead of writing out hundreds of individual DOMAIN-SUFFIX lines.

GEOSITE,netflix,Proxy
GEOSITE,cn,DIRECT

Before using this type, confirm the client has already downloaded and loaded the corresponding rule set file, or the rule will silently fail to take effect because the category data can't be found.

PROCESS-NAME and MATCH

PROCESS-NAME matches by the name of the process that initiated the connection, useful for assigning a dedicated proxy policy to a specific app — common on desktop setups. MATCH carries no match value and represents "whatever wasn't caught above, handle it this way" — it should always be the last line in the rule list.

PROCESS-NAME,Steam.exe,Proxy
MATCH,DIRECT

Match priority and first-match-wins

Once all these rule types sit together in one config, what actually determines behavior is their order in the list, not any inherent "weight" of the type itself. Clash doesn't automatically give a DOMAIN rule priority over a DOMAIN-KEYWORD rule placed above it — order is entirely determined by physical position in the list.

Here's an easy trap to fall into:

DOMAIN-KEYWORD,youtube,Proxy
DOMAIN-SUFFIX,youtube.com,DIRECT

The intent might be to route YouTube through a proxy while sending a specific subdomain (say, a static-asset domain that works fine directly) straight through. But because the DOMAIN-KEYWORD rule comes first, any domain containing the string youtube gets caught by it first and sent through the proxy — the more specific DOMAIN-SUFFIX rule below never gets a chance to run. To make the exception work, move it above the broader rule:

DOMAIN-SUFFIX,youtube.com,DIRECT
DOMAIN-KEYWORD,youtube,Proxy

After the change, the precise suffix rule gets checked first — if it matches, the connection goes direct and matching stops. Only domains containing youtube that don't match this precise rule fall through to the keyword rule and get proxied.

If a rule looks correctly formatted but "never fires," the first thing to check isn't the syntax itself — it's whether a broader rule above it has already caught and matched the same traffic.

Ordering tips for custom rules

Building on the principles above, here's a practical ordering approach that noticeably cuts down on debugging caused by rules overriding each other.

  1. LAN and private addresses first: use IP-CIDR with no-resolve to allow private ranges through, preventing any later rule from mistakenly sending local traffic into the proxy.
  2. Precise exceptions right after: for any "category goes through proxy, but a specific item goes direct" scenario (or vice versa), put the specific DOMAIN or DOMAIN-SUFFIX exception ahead of the broader category rule it's an exception to.
  3. Category rule sets in the middle: place GEOSITE and common ad/privacy block lists after the exceptions but before broad keyword rules, letting the category sets handle most routine domains first.
  4. Broad keyword matches near the end: DOMAIN-KEYWORD has the widest match range and the highest chance of collateral matches, so it should only run after all the more precise rules have already had a chance.
  5. Region/IP-attribution rules next: GEOIP is generally there to handle connections that domain rules didn't cover and that already have a resolved IP, so it typically comes after domain-based rules.
  6. MATCH catch-all as the last line: everything not matched by any rule above finally lands here, usually pointing to a default proxy group or direct connection depending on your network policy.

A simplified example arranged in this order:

IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
DOMAIN-SUFFIX,cn-cdn.example.com,DIRECT
GEOSITE,cn,DIRECT
GEOSITE,geolocation-!cn,Proxy
DOMAIN-KEYWORD,ads,REJECT
GEOIP,CN,DIRECT
MATCH,Proxy

The logic reads coherently: handle LAN first, then handle a specific CDN domain that should always go direct, then let category rule sets handle most domestic and international sites, then use a keyword rule to catch scattered ad domains, let GEOIP catch IPs the earlier domain rules missed but that are already resolvable, and finally MATCH wraps up by sending everything else to the proxy group.

Common mistakes and how to debug them

Here are a few situations that come up most often when debugging rules in practice, to help pinpoint the issue quickly.

  • A rule never seems to fire: first check whether a broader rule above it is already catching the same traffic; try temporarily moving the rule to the very top of the list to confirm the syntax itself is fine, then work on ordering.
  • Rules exist after MATCH: those rules will never run — move them above MATCH.
  • IP-based rules don't apply to domain-based connections: check the client's DNS and resolution mode settings to confirm the connection already has a target IP at match time; otherwise switch to the corresponding domain-based rule.
  • A keyword rule catches too many unrelated domains: swap the keyword for a fuller string, or switch to DOMAIN-SUFFIX to limit it to a specific suffix and cut down on unrelated matches.
  • A rule set fails to load, disabling an entire category of rules: confirm the rule set file has been downloaded locally and is referenced with the correct path in the config — network issues or a wrong path will disable that whole block of rules.

After changing rules, it's worth testing one new or adjusted rule at a time in a small scope, confirming the match result is what's expected before stacking the next change — changing too much at once makes debugging harder. Most clients automatically reload rules after saving the config; if the expected effect doesn't show up, try manually triggering a config reload to rule out caching issues.

Keep frequently changing custom exceptions grouped near the top of the file, and leave stable category rule sets and the catch-all at the bottom — future edits only need to touch that top section, which noticeably cuts maintenance overhead.

Get the Clash Client

Once you understand rule syntax, you can import a config into an actual client and verify results line by line.

Download Client