1. What rules do and the basics of their syntax
rules is an ordered list at the top level of a configuration file. It determines which policy handles each connection; it does not create proxies or run speed tests. The target at the end of a rule can be a built-in policy such as DIRECT or REJECT, or the exact name of a proxy node or policy group already defined in the configuration. Names must match exactly, including spaces and capitalization.
This guide covers standard rule mode in Clash Nyanpasu with the mihomo core. Extensions supported by different Clash cores are not always the same. When migrating a configuration, first check the core information in the client or its startup log. The basic domain rules below illustrate traffic routing, but do not imply that every core supports the same advanced fields.
Check the mode before editing rules
- Rule mode: Routes connections according to the
ruleslist. This is the mode covered in this guide. - Global mode: Uses a global policy instead of routing traffic through the standard
ruleslist. - Direct mode: Sends traffic directly, so it cannot be used to test proxy routing rules.
In YAML, mode: rule enables rule mode. The client interface may also let you switch the active mode, so check the current runtime state as well. System proxy and TUN settings determine which traffic reaches the core; they do not control rule priority. Connections that never reach the core will not be intercepted just because you added a rule.
mode: rule
rules:
- DOMAIN,portal.example.com,DIRECT
- DOMAIN-SUFFIX,example.org,Proxy Selection
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,Proxy Selection
2. Common rule types and field positions
A standard rule usually takes the form “type, match value, target policy.” MATCH does not need a match value; some IP rules can include no-resolve. Separate fields with commas, keep a hyphen and a space before each list item, and use spaces—not tabs—for indentation.
| Type | Example | What it matches |
|---|---|---|
DOMAIN | DOMAIN,api.example.com,DIRECT | Matches only the exact domain api.example.com. |
DOMAIN-SUFFIX | DOMAIN-SUFFIX,example.com,DIRECT | Matches the root domain and all its subdomains. |
DOMAIN-KEYWORD | DOMAIN-KEYWORD,example,Proxy Selection | Matches a string anywhere in the domain name, which can cast a wide net. |
IP-CIDR | IP-CIDR,10.0.0.0/8,DIRECT,no-resolve | Matches an IPv4 address range. |
IP-CIDR6 | IP-CIDR6,fc00::/7,DIRECT,no-resolve | Matches an IPv6 address range. |
GEOIP | GEOIP,CN,DIRECT | Matches according to the geographic database entry for the destination IP. |
RULE-SET | RULE-SET,business,Proxy Selection | References the rule provider named business. |
MATCH | MATCH,Proxy Selection | Catches connections that did not match any preceding rule. |
Domain rules do not include URL paths
DOMAIN matches a hostname, not a full URL. Write api.example.com, not https://api.example.com/login. Standard domain rules cannot distinguish between /login and /images on the same host. A path in an HTTPS request is not a condition that ordinary domain-based routing can use directly.
DOMAIN-SUFFIX,example.com matches example.com and a.example.com, but not notexample.com just because it contains similar characters. DOMAIN-KEYWORD, by contrast, matches a string and can cast a wider net, so it generally belongs after specific domain exceptions.
3. Rule priority: top to bottom, first match wins
Standard rule lists do not automatically prioritize domain rules over IP rules, or specific rules over broad ones. The core checks rules in order and applies the target policy as soon as one matches; later rules cannot override it. A specific rule only works as an exception when it comes before a broader rule.
rules:
- DOMAIN,api.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,Proxy Selection
- MATCH,Proxy Selection
api.example.com: Matches rule 1 and goes direct.www.example.com: Rule 1 does not match; rule 2 matches and sends it to “Proxy Selection.”example.net: Neither of the first two rules matches, so rule 3 catches it.
If you move rule 2 above rule 1, api.example.com will match the suffix rule first, and the direct-connection exception will no longer work. Similarly, putting MATCH at the top of the list prevents later standard rules from ever being reached.
Recommended rule order
- Specific exceptions: Exact domains, internal services, or device-specific conditions that need separate handling.
- Local network destinations: Add private address ranges that fit your network to keep internal services from going through a proxy.
- Service rules: Specific domain suffixes, service rule sets, and intentional block rules.
- Broad categories: For example, a direct rule based on GEOIP.
- Final catch-all: One
MATCHrule to specify where otherwise unmatched traffic goes.
This ordering is easy to maintain, but it is not a fixed sequence required by the core. If a service domain must use a proxy, put its rule before GEOIP,CN,DIRECT, even if the geographic database classifies its IP address as CN.
4. IP-CIDR, GEOIP, and no-resolve
IP-CIDR,192.168.0.0/16,DIRECT covers IPv4 addresses from 192.168.0.0 through 192.168.255.255. Use /32 to match a single IPv4 address or /128 for a single IPv6 address. Specify address ranges according to your needs; do not treat every private address as part of the same rule.
When the destination is a domain, an IP rule may need to resolve it before matching. Adding no-resolve means this rule will not initiate a DNS lookup just to resolve the domain; address matching can still occur if a usable destination IP is already available. It does not disable DNS for the whole client or skip every DNS request.
rules:
- DOMAIN,intranet.example.com,DIRECT
- 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
- GEOIP,CN,DIRECT
- MATCH,Proxy Selection
Known internal domains are listed first because an address rule with no-resolve cannot reliably identify their private IPs from the domain alone. GEOIP uses a database classification of the destination IP, not page content, domain registration location, or server brand. CDN addresses and database updates can affect the result.
5. Using RULE-SET with rule-providers
When you have many rules, you can put the match values in a rule provider and reference it with RULE-SET. rule-providers defines the data source and format; rules determines where it sits in the matching chain and which policy applies when it matches. Defining a provider does not make it participate in routing automatically—you still need to reference it in rules.
Example: a local domain rule set
This example uses a local file provider in mihomo. Place the rule set at the specified path in the configuration directory used by the core. Relative paths are resolved against the runtime working directory, so do not infer the path from where you downloaded the file. Check the client log to confirm the path actually being read.
rule-providers:
business:
type: file
behavior: domain
format: yaml
path: ./rules/business.yaml
rules:
- DOMAIN,health.example.org,DIRECT
- RULE-SET,business,Proxy Selection
- GEOIP,CN,DIRECT
- MATCH,Proxy Selection
The contents of ./rules/business.yaml are shown below. For the domain behavior, +.example.org matches the domain and its subdomains. Do not put a complete DOMAIN-SUFFIX,example.org,Proxy Selection rule line directly into a domain-type list.
payload:
- '+.example.org'
- 'api.example.net'
behavior: domain: The entries are domain matching expressions.behavior: ipcidr: The entries are IP address ranges.behavior: classical: The entries are rule conditions supported by the core, such asDOMAIN-SUFFIX,example.org. In most cases, do not include a target policy in each entry.
These three behaviors are not interchangeable. Remote providers also involve downloading, updating, and caching. When troubleshooting, first confirm that the provider loaded successfully, then investigate rule priority. Even if a rule set contains thousands of entries, its priority in the main list is determined by the position of its RULE-SET line. It cannot override a rule that has already matched above it.
6. Keeping custom rules across subscription updates
Updating a remote subscription may regenerate the configuration. If you edit the downloaded YAML directly, the changes may work now but disappear on the next update. A safer approach is to keep the original subscription and add your rules through a client-supported local override, merge, or script step, then verify the final order. Menu names vary by client version; saving subscription text is not the same as saving a persistent override.
- Back up the working configuration and note the selected profile, mode, and policy group names.
- In Profiles, confirm which configuration is active; do not edit an inactive copy.
- Add one specific domain rule first and make sure it appears before existing broad rules.
- Check the generated runtime configuration. Confirm there is only one
ruleslist, then verify its first rule, rule-set references, and finalMATCH. - Run a subscription update and check again that the rules remain and their order has not changed.
Merge tools can replace, append to, or prepend to a list. Seeing a new rule in the text does not prove that it works: a rule appended after MATCH is present but can never match. Check the output of script-based overrides as well, not just whether the script ran successfully. For YAML structure and field details, see the YAML Configuration Guide.
7. How to troubleshoot custom rules that do not work
Use the same destination host while troubleshooting, keep the selected policy group fixed, and change only one condition at a time. “Matched rule,” “target policy,” and “actual proxy chain” in the connections panel are different things. If a connection matches “Proxy Selection,” it is handed to that group; if the group is set to DIRECT, the connection still goes direct.
| Symptom | Check first | What to do |
|---|---|---|
| No request appears in the connections panel | Whether app traffic reaches the core | Check the system proxy, app proxy, or TUN routing. Fix the traffic entry point first. |
| A broader, existing rule matches | The actual order of custom rules | Move the specific exception above that rule and check whether the override only appends rules. |
| Policy not found warning | The group name at the end of the rule | Copy the full group name from the active configuration and check spaces, capitalization, and whether the configuration has changed. |
| RULE-SET failed to load | Provider name, path, and behavior | Check the startup log and file format. Fix loading errors before testing traffic. |
| Traffic still uses the old policy after a change | Whether an existing connection is being reused | Close the target connection and make a new request; refreshing an existing long-lived connection is not enough. |
| Rules disappear after a subscription update | Whether the change was saved to the generated file | Move the change to a persistent override and inspect the final configuration after updating. |
A minimal test
- Confirm that the active mode is Rule and the selected configuration has been applied.
- Add one
DOMAINrule for the domain you are actually testing and place it near the top of the list. - Save and apply the configuration. If there is a parsing error, restore the backup before making any further changes.
- Close any existing connection to that destination, then visit it again.
- In the connection details, check the destination host, matched rule, policy group, and actual egress route.
- Once the result is confirmed, expand the rule to use a domain suffix or rule set, then test the fallback path for unmatched traffic.
Maintaining rules comes down to three things: traffic must reach the core, the match conditions must agree with the connection details, and the rule must appear before any rule that would override it. Start with an exact domain to get a reproducible result, then add IP classifications and rule sets. This makes issues easier to isolate than changing many entries at once. For details on profiles, policy groups, and TUN, see the Glossary.