For custom rules, first set Global Routing to Config, then order rules from specific exceptions to broader matches, with FINAL last. This guide is for users who already have their own service and connection details and want to adjust Shadowrocket’s traffic routing. It covers rule syntax, editing steps, and verification methods; it does not provide access to any services.
Check Config first, then verify that the rules are active
Correct rule syntax does not guarantee that the current connection is using those rules. Before troubleshooting, check the current mode under Home → Global Routing, then confirm the selected configuration file in Config. This guide covers sequential matching in the [Rule] section of a configuration file—not the order of services or latency test results.
Config
RecommendedUse the rules in the current configuration to determine how connections are handled. The DOMAIN-SUFFIX, IP-CIDR, and FINAL examples below are based on this setup.
Best for: Writing, verifying, and maintaining custom traffic routing rules.
Proxy
Connections are handled through a proxy rather than by evaluating each rule in this configuration. If switching modes temporarily restores access, that means the routing path needs further investigation—not that a particular rule is necessarily wrong.
Best for: Briefly checking whether the proxy route works.
Direct
Connections are made directly. Editing a PROXY rule in the configuration is not a meaningful way to test rule behavior in this mode.
Best for: Checking direct connections on the current network.
Global Routing also includes Scene, which determines how connections are handled based on the selected scenario. If Scene is selected, first check which scene is active. To keep testing conditions consistent, you can temporarily switch to Config while verifying the examples, then restore your previous selection. Settings → On Demand controls when connections are made on demand; it does not replace rules for choosing how a destination is handled.
Rule syntax: rule type, match value, and policy
Most common rules use the order “rule type, match value, policy,” with fields separated by English commas. FINAL is an exception: it has no match value, so write it as FINAL,DIRECT or FINAL,PROXY. Don’t use Chinese commas or include a URL path or port in a domain match value.
| Rule type | Syntax example | What it matches |
|---|---|---|
DOMAIN | DOMAIN,api.example.com,PROXY | Matches this exact domain only. |
DOMAIN-SUFFIX | DOMAIN-SUFFIX,example.com,DIRECT | Matches example.com and its subdomains, but not notexample.com. |
IP-CIDR | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve | Matches the specified IPv4 range; in this example, 192.168.0.0 through 192.168.255.255. |
GEOIP | GEOIP,CN,DIRECT | Matches according to the geographic database classification of the destination IP—not the webpage language or domain suffix. |
FINAL | FINAL,PROXY | Applies this policy when none of the preceding rules match. |
For example, if the destination domain is api.example.com, enter only that domain as the match value for a DOMAIN rule. Don’t add https://, /login, or :443. HTTPS connections to a domain commonly use TCP port 443, but DOMAIN-SUFFIX does not check ports. To match by port, changing the domain string alone won’t work.
no-resolve is an optional parameter for IP-based rules. It prevents a domain lookup from being triggered solely to evaluate that rule; it does not disable DNS for the entire app. If a connection has a domain name but no destination IP available to match, a rule with this parameter may not match. For domain-based routing, use a domain rule rather than expecting an IP rule to match in every case.
Rules are checked from top to bottom: put specific exceptions first
With the basic rules covered here, connections are checked in order and the policy of the first matching rule is applied. Rules don’t jump ahead because they’re “more specific,” and policies from multiple matching rules aren’t combined. A common issue is placing a specific subdomain exception after a suffix rule that already matches the entire domain: the exception never gets a chance to run.
[Rule]
DOMAIN,api.example.com,PROXY
DOMAIN,blocked.example.com,REJECT
DOMAIN-SUFFIX,example.com,DIRECT
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
FINAL,PROXY
This [Rule] example illustrates rule order; it is not a complete configuration with all connection settings. The domains are examples, and connection details must come from information you already have. If the file already contains a [Rule] section, edit that section rather than adding a duplicate.
api.example.commatches the first rule and uses PROXY. Although it also matches the later domain suffix rule, that won’t change its policy to DIRECT.blocked.example.commatches the second rule and uses REJECT. Move this rule below DOMAIN-SUFFIX and the exception no longer works.www.example.commatches neither of the first two rules, so it reaches the third and uses DIRECT.- Connections to
192.168.1.20can match the fourth rule. Other connections that match none of the earlier conditions fall through to FINAL.
Bottom line: move exceptions up before adding rules
If a subdomain isn’t routed as expected, first check whether a rule above it already covers the entire suffix. Moving the specific exception above the broader condition is more effective than adding a duplicate rule.
The same principle applies to IP ranges. To use a different policy for one destination IP, place its /32 rule above the /24 or /16 rule that covers it. Broader conditions such as GEOIP generally belong after specific domains and IP ranges, so they don’t take over connections that need separate handling.
How PROXY, DIRECT, REJECT, and FINAL work together
The rule type defines what to match; the policy defines what happens after a match. PROXY sends a connection through the proxy route, DIRECT connects directly, and REJECT blocks the connection. Whether PROXY can complete a request still depends on the selected proxy and its connection status. A rule match does not guarantee that the remote service is reachable.
- PROXY
- Send matching connections through the proxy route. When testing, also check the service currently selected on Home and whether its connection is working.
- DIRECT
- Connect to the destination directly over the current network. This does not automatically select a faster route or guarantee that the destination is reachable from that network.
- REJECT
- Reject matching connections. A rule covering an overly broad domain suffix or IP range can affect related pages and resources.
- FINAL
- The final rule applies when no earlier rule matches. It is not a proxy service; it sends the remaining connections to the specified policy.
Use FINAL,DIRECT when the design is to proxy only explicitly listed destinations and connect directly to everything else. Use FINAL,PROXY when explicitly listed destinations should connect directly or be rejected, with everything else sent through the proxy. There’s no universally correct choice outside the context of your needs. Don’t keep switching fallback policies just because one site is temporarily unavailable.
A webpage may connect to several domains: the main page, images, login endpoints, and media resources can each match different rules. A DIRECT rule for the main domain doesn’t mean every connection on the page will use DIRECT. Add exceptions for the domains involved in actual requests instead of sending every unidentified destination to REJECT.
Edit and verify: change one thing at a time
Before making changes, save a copy of the current configuration and note the existing selection under Home → Global Routing. Keep subscription configurations, remote configurations, and local copies in Config distinct: updating a service list does not update rules, and a remote configuration update may overwrite edits made to the original file. Keep personal changes you want to retain in a configuration copy you can maintain, and review it after every update.
-
Check the routing mode
Go to Home → Global Routing → Config so this test uses the configuration rules. Note the currently selected proxy and don’t change it during testing.
-
Find the configuration file
Go to Config and confirm which configuration file is selected. Save a copy before opening the file’s edit option. If editing the text directly, find
[Rule]and check where the existing FINAL rule appears. -
Add an exception
Place the DOMAIN or DOMAIN-SUFFIX rule you want to test above any relevant broader rules and before FINAL. Add or change just one rule at a time; avoid changing DNS and connection settings at the same time.
-
Start a new connection
Save the changes and confirm that this configuration is still selected. Return to Home and reconnect. Close and reopen the destination page to create new connections; don’t judge the result based on an existing persistent connection.
-
Check the results
Review the app’s connection log to check the actual requested domain, destination address, and policy used. If the result differs from what you expected, look for a rule that could have matched earlier before changing the match value.
You can keep a test record with four fields: destination, expected result, actual result, and change made. For example, use one of your own API domains as the destination; expect PROXY, but observe DIRECT; then move only that DOMAIN rule above DOMAIN-SUFFIX. This helps distinguish a rule that didn’t match from a matched rule whose connection failed—and makes temporary changes easy to undo after testing.
- Wrong rule matched: If the actual policy differs from the expected one, first check Global Routing, the selected configuration file, and rule order.
- Correct rule matched, but the connection failed: If PROXY was applied but timed out, check the availability and protocol settings of your existing service. You don’t need to rewrite all your rules right away.
- Some resources failed: If the main page loads but images or login fail, check the domains of the failed resources—not just the domain in the address bar.
Troubleshooting: what to check when rules don’t work
I’ve added rules. Why is everything still going through the proxy?
Go to Home → Global Routing and confirm that the mode isn’t Proxy, then check the selected file in Config. If Config is selected, look for a broader PROXY rule above yours and make sure FINAL hasn’t been placed before your custom rules.
Should DOMAIN-SUFFIX include an asterisk?
To match example.com and its subdomains, use DOMAIN-SUFFIX,example.com,DIRECT. Don’t use *.example.com or include a protocol prefix. To match only one exact domain, use DOMAIN instead.
Why doesn’t IP-CIDR match after I added no-resolve?
First check whether the connection log shows a destination IP that can be matched. no-resolve won’t look up a domain just for this rule. If you want to route by domain, add a domain rule rather than assuming this parameter will supply the missing IP address.
My custom rules disappeared after an update. What should I do?
In Config, first check whether the current file was replaced by remote content or whether a different configuration is now selected. Compare it with your saved copy to restore your changes. Service subscription updates on Home and configuration updates in Config are separate actions, so track them separately while troubleshooting.
Can I use FINAL,REJECT instead of checking each rule?
Consider this design only if you intentionally want an allowlist and are prepared to maintain every destination that needs to work. It rejects all connections not handled by an earlier rule. For routine troubleshooting, keep the existing fallback policy and test with specific DOMAIN exceptions to avoid blocking a large number of resources at once.
After testing, restore the previous routing mode, remove test rules, and confirm that FINAL is still last. Good rule maintenance isn’t about the number of entries: each exception should have a clear purpose, every update should be checked for changes, and each failed connection should be diagnosed as either a matching issue or a connection issue.