How to Write Custom Clash Rules: DOMAIN, IP-CIDR Syntax and Matching Priority Explained

A practical guide to common Clash rule types, top-to-bottom matching, the no-resolve option, and troubleshooting rules that do not take effect.

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

  1. Loopback, LAN, and specific destinations that must connect directly.
  2. Specific DOMAIN, DOMAIN-SUFFIX, or IP-CIDR exceptions that should override general rules.
  3. Ad blocking, service categories, GEOSITE, or external rule sets.
  4. GEOIP rules by region and other broad matches.
  5. 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.

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.

Download Clash Choose a client by platform