Check the rule mode and active configuration first
To always connect directly to a domain, switch the client to Rule mode, then place your custom entry near the top of the existing rules: list. Save and reload the configuration, then open the connections list to check which rule matched and which outbound was used. Global mode routes traffic according to the global policy, while Direct mode connects without rule-based routing; neither is suitable for testing rule order.
Clash is a common name in the client and core ecosystem. Clash Meta was later renamed mihomo. Domain rules, CIDR rules, and sequential matching are common configuration features, but supported rule-set formats and additional rule types depend on the core in use. The client interface and the core are separate components. When troubleshooting, check the About page or core information panel to confirm which core is running.
- Open the currently active configuration and back up the original file or export the configuration first.
- Check the names of existing proxy groups, such as
Proxy, including capitalization, spaces, and spelling. - Use the client's override, merge, or custom rules feature to add a small number of rules.
- After reloading, inspect the active configuration to confirm the new rules actually appear in
rulesand are not just saved in the editor.
Basic syntax: type, match value, outbound
Most standard rules follow the structure type,match value,target. The target can be a built-in option such as DIRECT or REJECT, or an existing proxy node or group in the active configuration. MATCH takes no match value; write it as MATCH,target and usually put it last as the fallback.
rules:
- DOMAIN,api.example.com,DIRECT
- DOMAIN-SUFFIX,example.org,DIRECT
- DOMAIN-KEYWORD,telemetry,REJECT
- IP-CIDR,192.168.50.0/24,DIRECT,no-resolve
- IP-CIDR6,fd00::/8,DIRECT,no-resolve
- MATCH,Proxy
This example is intended to replace or merge with an existing rule list. It assumes the configuration already defines a Proxy group. If the actual group is named Proxy, use that exact name; pasting these lines alone won't create a group or proxy node. The reserved domains in the example illustrate matching boundaries. Replace them with the real domains you need to control.
| Type | Matches | Use case |
|---|---|---|
DOMAIN | Exact domain match | Route a single API or sign-in endpoint differently |
DOMAIN-SUFFIX | The domain itself and its subdomains | Apply the same policy across a domain and its subdomains |
DOMAIN-KEYWORD | Domains containing a specified string | Use when a broader match is intentional |
IP-CIDR | Target IPv4 address range | Local networks and fixed service addresses |
RULE-SET | A declared rule provider | Manage a large set of domains or IP ranges in one place |
MATCH | Connections not matched by earlier rules | Default outbound at the end of the list |
DOMAIN-SUFFIX does not match any arbitrary string ending
DOMAIN-SUFFIX,example.com,DIRECT matches example.com and img.example.com, but not notexample.com. There's no need to write *.example.com. Don't include https://, a port, or a path in the domain field. Rules match connection details, not the full URL shown in the browser's address bar.
To match only api.example.com, use DOMAIN for a narrower scope. DOMAIN-KEYWORD,example,DIRECT may also match other domains containing the same string. For sign-in, payment, or internal business systems, start with an exact match and broaden it only if needed.
Rule order: top to bottom, first match wins
A standard rules list is evaluated in order. Usually, the first matching rule determines the outbound; Clash doesn't collect every match and automatically pick the most specific one. Domain rules don't inherently outrank IP rules, and exact domain rules don't automatically take precedence over suffix rules. Put any exception that needs to run first near the top.
rules:
- DOMAIN,api.example.com,Proxy
- DOMAIN-SUFFIX,example.com,DIRECT
- MATCH,Proxy
With this order, api.example.com uses Proxy, while www.example.com connects directly. If you swap the first two rules, the API domain matches the suffix rule first, so the exact-match rule below it never runs. This is a common reason why a configuration loads successfully but traffic behaves the same after adding rules.
Where to place custom rules
- Put specific exceptions before general rules: Place a special outbound rule for one domain before a rule that covers the entire domain family.
- Put custom fixes before related subscription rules: If a subscription rule set already matches the target domain, appending a custom rule usually won't change the outcome.
- Put fallback rules last: Ordinary rules after
MATCHcan't handle connections already caught by that fallback. - Keep security boundaries explicit: A direct-connect rule near the top can bypass subscription block rules. Add exceptions only for domains you're sure should be allowed.
So, putting custom rules before subscription rules is a way to control which rule takes precedence, not a requirement to place every custom entry at the very top. If existing block rules or local network rules need to run first, order the list to suit your needs. Then review the full active list, not just the lines you added.
IP-CIDR and no-resolve: controlling DNS lookups for rule matching
IP-CIDR,192.168.50.0/24,DIRECT,no-resolve matches the IPv4 range and routes it directly; /24 is the network prefix length. Use /32 for a single IPv4 address and /128 for a single IPv6 address. This is the destination address, not your device's source address.
When the connection target is still a domain, the core may perform a DNS lookup to evaluate a rule that requires the target IP. no-resolve prevents this IP rule from initiating a lookup just to check for a match. It does not disable DNS, guarantee a direct connection, or prevent later rules or the actual connection from requiring a lookup.
- CIDR matching still works when the target is already an IP address or the core has a usable, actual destination IP.
- If the target is a domain and no IP is available, an IP rule with
no-resolvegenerally won't look up the address just to match it. The connection continues to the next rule. - Use this option for local network addresses and explicit IP-based direct-routing needs. If you want to match an IP range based on a domain's DNS result, also consider how DNS behaves without this option.
For a company intranet, the subnet rule above is easy to test if an app connects directly to 192.168.50.10. If it uses an internal domain that resolves to that address, add an explicit direct-connect rule for the domain first and make sure DNS can resolve the company hostname. Routing and DNS reachability are separate issues; adding DIRECT won't fix an incorrectly configured DNS server.
RULE-SET syntax: provider definition and rule reference
For larger rule lists, declare a provider under rule-providers, then reference it with RULE-SET,provider-name,target. This is different from proxy-providers, which provide proxy nodes. The example below uses a local YAML domain rule set with mihomo: create the file first, then merge the entries into the main configuration.
Step 1: Create a local domain rules file
Create rules/local-direct.yaml in a configuration directory the core can access. Use payload for the file contents because the provider is declared with behavior: domain. Add only domain match values here; don't include the DOMAIN-SUFFIX type or an outbound target.
payload:
- 'example.com'
- '+.example.org'
Here, example.com matches the exact domain, while +.example.org matches the domain itself and its subdomains. Domain notation in a rule set works at a different level from DOMAIN-SUFFIX in the main configuration, so don't use the two interchangeably.
Step 2: Declare and reference the provider
rule-providers:
local-direct:
type: file
behavior: domain
format: yaml
path: ./rules/local-direct.yaml
rules:
- RULE-SET,local-direct,DIRECT
- MATCH,Proxy
The name local-direct must match exactly in both the definition and the reference. Relative paths are resolved from the core's working directory, which may not be next to the subscription file you're editing. If the file can't be read, check the actual path and permissions in the core log. type: file reads a local file; it doesn't download content from the internet.
If you use behavior: classical, each rule-set entry needs a rule type, such as DOMAIN-SUFFIX,example.org, but still no outbound target; the outer RULE-SET specifies the target. All matching entries in the rule set occupy the position of its reference in the main list—they don't get extra priority. Placing the reference after MATCH won't route traffic as intended either.
Verify and troubleshoot: check the matched rule, then the outbound chain
Add only one to three rules at a time. Check the configuration syntax before reloading. YAML uses spaces for indentation, not tabs. If rules: already exists, merge the entries into that list instead of adding another top-level key with the same name at the end of the file. Duplicate keys may overwrite earlier content or cause a parsing error.
- Make sure traffic reaches the core. The browser must use the system proxy, the app must be explicitly configured to use a proxy, or TUN must capture the traffic. Connections that never reach the core won't be evaluated against these rules.
- Check the test port. If the active configuration sets
mixed-portto7890, use the command below to route a request explicitly through the local HTTP proxy. Change the port if your configuration uses a different one. - Check a new connection. Search for the target domain in the connections list and expand the entry to see the rule type, match value, and outbound chain. Existing long-lived connections may continue using the old route; close the connection and try again.
- Distinguish the proxy group from the final node. Matching
Proxymeans the connection entered that group. If the group's current selection isDIRECT, the connection still goes direct.
curl --proxy http://127.0.0.1:7890 --head https://example.com
This command sends a test request explicitly through the local proxy. An HTTP status code alone doesn't prove that routing worked. Check the matched rule in the client as well. A domain may redirect, and a browser page may request resources from several domains, so check each connection you need to control.
Troubleshooting checklist for three common problems
- Configuration fails to load: Check indentation, commas, proxy group names, and whether the provider referenced by
RULE-SETexists. Start with the first error in the log. - Configuration loads, but the rule doesn't match: Check the running mode, rule order, actual request domain, and active configuration. If the connection shows only an IP, domain matching depends on whether the core has domain information.
- Rule matches, but the connection fails: Check DNS, the selected node, the destination service, and local routing. A rule match confirms the route was selected; it doesn't guarantee that route is reachable.
With TUN enabled, some system traffic, local network access, or routes excluded in the configuration may not take the expected path. An app's built-in proxy can also change how traffic enters the core. First test the rule with an explicit proxy command, then check the browser or target app to confirm which traffic TUN captures. This helps distinguish a rule problem from traffic that never reached the core.
After verification, update the subscription once more and check that your rules remain in place. A reliable setup keeps exceptions in local overrides, general rules in the subscription, and an explicit fallback at the end. Check the connection log after every change. For configuration options and traffic interception methods, see the Advanced Configuration guide or the Help Center.