Understanding the Anatomy of a Clash Rule
Basic Clash and mihomo rules usually use comma-separated fields. The most common structure is “rule type, match value, target policy.” For example, DOMAIN-SUFFIX,github.com,PROXY sends the connection to the policy group named PROXY when the destination domain ends with github.com. Policy names are case-sensitive and must exactly match the names in proxy-groups.
rules:
- DOMAIN,api.example.com,DIRECT
- DOMAIN-SUFFIX,github.com,PROXY
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,FINAL
Here, DIRECT and REJECT are built-in actions, while PROXY and FINAL can be user-defined policy groups. A rule does not need to name a specific server to be valid; the usual approach is to point it to a policy group, which then selects the actual node through manual selection, latency testing, or failover.
YAML Indentation and Rule Placement
rules is a top-level configuration field, and list items are typically indented by two spaces. Do not use Tab characters, and do not place rules inside proxy-groups or rule-providers. After editing, reload the configuration in the client; saving the file without reloading may leave the running core using the old content.
Using a typical desktop client as an example, open the currently enabled profile on the configuration page. After editing, choose “Save” or “Reload.” Then open the “Connections” page and visit the target domain to see the matched rule type and policy chain. Menu names vary slightly between clients, but the verification points are the same: the active configuration file, running core, and connection logs must all correspond.
How to Choose Between DOMAIN, DOMAIN-SUFFIX, and DOMAIN-KEYWORD
DOMAIN: Matches Only the Exact Domain
DOMAIN is suitable for a single hostname. The rule below matches only api.example.com; it does not match www.example.com and does not automatically cover v2.api.example.com.
rules:
- DOMAIN,api.example.com,PROXY
Use DOMAIN when you need to assign a separate policy to a login endpoint, update server, or specific API. Its scope is explicit, so it is less likely to affect other services under the same parent domain.
DOMAIN-SUFFIX: Matches the Root Domain and Its Subdomains
DOMAIN-SUFFIX,example.com,PROXY typically matches example.com, www.example.com, and a.b.example.com. This is the most commonly used type for custom domain routing and works well when multiple subdomains of one site should use the same policy.
rules:
- DOMAIN-SUFFIX,example.com,PROXY
- DOMAIN-SUFFIX,example.net,DIRECT
The suffix value should be the domain itself. Do not add https://, a path, a port, or a wildcard. The correct value is example.com, not https://example.com/path or *.example.com. Clash rules match the connection target, not the complete path of a web URL.
DOMAIN-KEYWORD: Matches a String Within the Domain
DOMAIN-KEYWORD checks whether a domain contains the specified string. For example, DOMAIN-KEYWORD,google,PROXY can match multiple domains containing google. It is concise, but broader than a suffix rule and may also match unrelated domains.
| Rule Type | Example Target | Matches? | Best Use |
|---|---|---|---|
DOMAIN,api.example.com |
api.example.com |
Yes | A fixed endpoint or single host |
DOMAIN,api.example.com |
v2.api.example.com |
No | Does not cover subdomains |
DOMAIN-SUFFIX,example.com |
img.example.com |
Yes | Consistent routing for a site and its subdomains |
DOMAIN-KEYWORD,example |
example-cdn.net |
Yes | Domains are scattered but share a stable keyword |
IP-CIDR, IP-CIDR6, and the Role of no-resolve
CIDR Defines an Address Range
IP-CIDR matches IPv4 addresses or subnets. 192.168.1.0/24 covers addresses from 192.168.1.0 through 192.168.1.255, while 1.1.1.1/32 matches a single IPv4 address. IPv6 uses IP-CIDR6, such as 2001:db8::/32.
rules:
- 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
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
These rules are commonly used for loopback addresses, home LANs, and corporate intranets that should connect directly. If your computer shares a proxy with devices on the same subnet through an HTTP or mixed port, place LAN rules before broad proxy rules so router admin pages, NAS devices, and printers do not get sent through a proxy node.
no-resolve Does Not Disable DNS
When the connection target is still a domain, the core may need to obtain its IP address to determine whether an IP-based rule matches. Adding no-resolve to the end of an IP-CIDR or GEOIP rule tells the core not to actively resolve the domain solely for evaluating that rule. If the connection target is already an IP, the rule can still be compared normally.
rules:
- DOMAIN-SUFFIX,internal.example,DIRECT
- IP-CIDR,10.20.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT,no-resolve
- MATCH,PROXY
In this set of rules, internal.example is handled first by the domain rule; when the target is directly written as 10.20.3.8, the IP-CIDR rule handles it. no-resolve does not turn off the configured DNS module, prevent an application from making its own DNS queries, or turn a domain rule into an IP rule.
Why IP Rules Can Be Unreliable
Large websites often use CDNs, so the same domain may resolve to different IPs depending on the network, time, and DNS server. A temporary resolution written as a /32 rule may match briefly and then stop working when the address changes. Prefer domain rules for services that can be described by stable domains; use IP rules when the target itself is a fixed address, a private subnet, or a case that genuinely depends on geographic IP data.
Rule Priority: First Match from Top to Bottom, Not Rule Type
The core principle of Clash rules is ordered matching. A connection is checked starting with the first item in the rules list; once a rule matches, its specified policy is applied immediately and later rules are skipped. There is no fixed type priority in which “DOMAIN always outranks IP-CIDR” or “REJECT automatically outranks DIRECT.”
rules:
- DOMAIN,download.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,PROXY
- MATCH,FINAL
When visiting download.example.com, the first rule already matches, so the result is DIRECT. When visiting www.example.com, the first rule does not match and the second one does, so the result is PROXY. If the rules are reversed, the download domain is caught by the suffix rule first and the intended exact-match direct rule never gets a chance to run.
Recommended Ordering
- Loopback, LAN, and specific destinations that must connect directly.
- Specific DOMAIN, DOMAIN-SUFFIX, or IP-CIDR exceptions that should override general rules.
- Ad blocking, service categories, GEOSITE, or external rule sets.
- GEOIP rules by region and other broad matches.
- Use MATCH last to catch connections that matched nothing above.
This is not a format enforced by the core, but a maintainable way to organize rules. The principle is: “The narrower the scope and the higher the exception priority, the earlier the rule belongs.” If an exception must override a large rule set supplied by a subscription, it must appear before the corresponding RULE-SET.
MATCH Belongs at the End
MATCH has no match value and catches every connection that has not matched earlier. Older configurations may also use FINAL as the last rule type; current mihomo configurations generally use MATCH. Whichever you choose, placing it in the middle means rules after it will never run.
rules:
- DOMAIN-SUFFIX,example.org,DIRECT
- RULE-SET,private,DIRECT
- RULE-SET,streaming,MEDIA
- GEOIP,CN,DIRECT,no-resolve
- MATCH,PROXY
The Roles of GEOIP, GEOSITE, and RULE-SET
GEOIP Matches the Region of the Destination IP
GEOIP,CN,DIRECT evaluates the destination IP, not the domain’s registration country, the server operator, or the language of the webpage. The database affects the result, so the client core and geographic database must remain available. CDN edge nodes, Anycast addresses, and database update delays can all produce classifications that differ from intuition.
With Fake-IP DNS mode enabled, a domain connection can still retain its domain information for the rule engine to evaluate; the core handles resolution and mapping. Do not create a proxy rule for the entire 198.18.0.0/16 range just because it appears in the connection list. This reserved range is used for Fake-IP mapping and does not represent the website’s real server addresses.
GEOSITE Matches Domain Categories
mihomo supports GEOSITE rules, which match domains by categories in a geographic data file. For example, GEOSITE,cn,DIRECT uses a domain set, while GEOIP,CN,DIRECT uses regional IP data. The names are similar, but the evaluation stage and data source are different.
rules:
- GEOSITE,category-ads-all,REJECT
- GEOSITE,cn,DIRECT
- GEOIP,CN,DIRECT,no-resolve
- MATCH,PROXY
GEOSITE category names depend on the dataset in use, and not every older Clash core supports them. When moving a configuration between clients, first confirm the core type and supported rules. You can view the active core on the client’s “Settings” information page, or run mihomo -v in a terminal to check the version output.
RULE-SET References a Rule Provider
RULE-SET does not contain domains directly; it references a rule collection defined under rule-providers. The private value below must match the provider key exactly. A provider’s behavior may be domain, ipcidr, or classical, and the file content must match that behavior type.
rule-providers:
private:
type: http
behavior: classical
format: yaml
path: ./ruleset/private.yaml
url: https://rules.example.com/private.yaml
interval: 86400
rules:
- RULE-SET,private,DIRECT
- MATCH,PROXY
interval: 86400 checks for updates every 86,400 seconds, or 24 hours. If a rule provider download fails, first check that the URL is reachable and the file format matches behavior, then verify that the client can write to ./ruleset/. Pasting a remote URL into rules does not automatically create a rule set.
Port, Process, and Network Entry Rules
DST-PORT and SRC-PORT
DST-PORT matches the destination port. For example, DST-PORT,443,PROXY covers a wide range of HTTPS and other connections using port 443. SRC-PORT checks the local source port, but applications frequently change their ephemeral source ports, so it is rarely suitable as a long-term routing condition.
rules:
- DST-PORT,22,DIRECT
- DST-PORT,853,PROXY
- MATCH,FINAL
The port in a port rule is the destination service port, not Clash’s listening port. mixed-port: 7890 means the local proxy entry listens on port 7890; that is separate from the destination port 80 or 443 used to access a website. Do not use DST-PORT,7890 to match all traffic passing through the mixed port.
PROCESS-NAME Support Depends on the Platform and Capture Method
mihomo can route by process name or path on some desktop platforms, for example PROCESS-NAME,curl,DIRECT. Process rules depend on connection and process information supplied by the operating system and may be unavailable on Android, iOS, containers, or restricted-permission environments. Executable names also vary by system; on Windows they commonly include .exe. Recheck them when migrating a configuration.
rules:
- PROCESS-NAME,curl,DIRECT
- PROCESS-NAME,backup-client.exe,DIRECT
- DOMAIN-SUFFIX,example.com,PROXY
- MATCH,FINAL
System proxy mode mainly receives traffic from applications that follow HTTP or SOCKS proxy settings, while TUN mode captures a broader range of IP traffic through a virtual network interface. Rule order is unchanged between the two modes, but the target information visible to the core may differ. Before troubleshooting process rules, confirm that the connection actually entered Clash and check whether the connection details show a process name.
When a Rule Does Not Work: Troubleshoot in This Order
Step 1: Confirm You Edited the Active Configuration
A client may store subscription profiles, local profiles, and override profiles at the same time. First check the name and update time of the active profile, then confirm that the rule made it into the running configuration. Some clients replace the original profile during subscription updates, so custom content should go in a supported override, merged configuration, or separate local profile.
- Check whether the active configuration has just been reloaded.
- Check whether configuration parsing reports YAML indentation or field errors.
- Confirm that the target policy group exists and that its name and capitalization match exactly.
- After a subscription update, check again that the custom rule is still present in the final configuration.
Step 2: Read the Actual Match from the Connection Log
Open the client’s “Connections” or “Logs” page, then make the request again. Browsers may reuse existing TCP, QUIC, or HTTP/2 connections, so simply refreshing the page may not create a new connection after a rule change. Close the relevant tab, wait a few seconds, and retry, or terminate the old connection from the connection list.
Suppose api.example.com should connect directly, but the log shows DOMAIN-SUFFIX,example.com and routes it through a proxy group. That means the broader rule comes first. If the log shows MATCH directly, the issue is usually a domain typo, invalid rule format, or a rule set that failed to load.
Step 3: Check Whether You Are Seeing a Domain or an IP
When an application connects directly to an IP, DOMAIN rules naturally cannot match. If an application uses its own encrypted DNS, internal cache, or QUIC connection, the information visible to the core may also differ from the browser’s address bar. Host, destination address, network type, and process fields in the connection details are more reliable than guessing from the webpage domain.
If TUN is enabled, you can temporarily compare connection records in system proxy mode and TUN mode, but do not repeatedly change DNS, rules, and nodes at the same time. Change one variable at a time: first confirm that traffic enters the core, then verify the target information, and finally check the rule order.
Step 4: Verify the Policy Group, Not Just the Rule Name
A rule matching PROXY only means that the connection was handed to that policy group. If PROXY is currently set manually to DIRECT, the actual egress is still direct. If it points to a latency-testing group, the actual node is selected from the group’s test results. Connection details usually show the full chain, similar to “Rule → Policy Group → Node.”
Step 5: Reproduce the Issue with a Minimal Rule Set
Large subscriptions may contain tens of thousands of rules, making conflicts hard to identify when editing the full configuration. Create a temporary local profile containing only the required proxies, one policy group, two or three test rules, and a final MATCH. Once the test succeeds, put the exact rules back before the relevant rule set in the production configuration.
rules:
- DOMAIN,test.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,PROXY
- MATCH,DIRECT
During testing, record the target domain, connection time, matched rule, and final policy. Test three times, closing the old connection before each attempt. Consistent results across all three tests indicate stable rule ordering. If the first attempt matches the old policy and the next two match the new one, connection reuse or DNS caching is usually responsible—not random changes in the matching algorithm.
A Complete Rule Example That Is Easy to Maintain
The structure below handles LAN traffic and explicit exceptions first, followed by ads, service categories, domains in mainland China, and IP addresses in mainland China. Remaining connections are then handed to a proxy group. This demonstrates ordering; adjust the policy group names and rule-set URLs to fit your configuration.
rules:
# Local Host and LAN
- 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
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
# Explicit Exceptions
- DOMAIN,updates.example.com,DIRECT
- DOMAIN-SUFFIX,work.example,WORK
- DOMAIN-SUFFIX,github.com,PROXY
# Category Rules
- GEOSITE,category-ads-all,REJECT
- RULE-SET,private,DIRECT
- RULE-SET,streaming,MEDIA
# Broad Rules
- GEOSITE,cn,DIRECT
- GEOIP,CN,DIRECT,no-resolve
# Fallback
- MATCH,PROXY
Add comments to rule groups during maintenance, and keep manual exceptions before large rule sets. After each change, test one explicit domain, one mainland-China site, one proxied site, and one LAN address such as the router at 192.168.1.1. Expand the rule scope only after all four connection types behave as expected.
Effective traffic routing is not about stacking more entries. Each rule should have an explainable scope, a verifiable position, and a match result that can be reproduced from the logs. When something goes wrong, inspect these five layers in order—active configuration, connection target, first matching rule, policy chain, and actual egress—to locate the problem quickly.