This guide is for readers who have imported their own configuration into Shadowrocket and need to route specific domains differently. It uses verifiable examples to explain first-match processing, the three common policies, and the FINAL fallback, then gives you a checklist for rules that don't behave as expected.
Check the routing mode: Config and first-match processing
Check Global Routing on Home. With Config selected, connections follow the rules in the active configuration file. Proxy and Direct apply their respective global routing modes, so they aren't suitable for testing an individual custom rule. Scene uses a separate, scene-based routing mode and shouldn't be confused with rule-by-rule testing in Config. Before troubleshooting, note the active configuration file and selected proxy so you don't edit one file while testing another.
Read rules from the top of the list, checking each line to see whether the request meets its conditions. Once a rule matches, its policy applies and processing stops; later rules aren't checked. Domain suffixes, destination IP ranges, and geolocation are different types of conditions, so don't infer priority from their names in the file. If a request could match two lines, the first matching line determines the result.
How to read a rule: condition, target, and policy
A typical rule uses commas to separate its fields. DOMAIN-SUFFIX,example.com,PROXY means requests for example.com or any domain ending in .example.com use PROXY. GEOIP,CN,DIRECT means requests matching that IP geolocation condition use DIRECT. Here, example.com is a documentation example, not a service address to import. When editing rules, keep keywords, commas, and policy names in English; don't use localized punctuation.
DOMAIN-SUFFIX,example.com,PROXY
DOMAIN-SUFFIX,ads.example.com,REJECT
IP-CIDR,192.0.2.0/24,DIRECT
GEOIP,CN,DIRECT
FINAL,PROXY
The five lines above illustrate the format; they aren't intended to replace your existing configuration. 192.0.2.0/24 is a documentation-only example range. In an IP-CIDR rule, the number after the slash is the prefix length; use the destination range you actually need to match. REJECT blocks matching requests, DIRECT connects to the destination without using the selected proxy, and PROXY routes traffic through the proxy path specified by the active configuration. Whether DIRECT can reach a destination still depends on your network and the destination's availability.
Domain and IP conditions
- DOMAIN-SUFFIX
- Match a domain and its subdomains
- IP-CIDR
- Match a specified destination IP range
- GEOIP
- Match based on the destination IP's geolocation
Domain and IP conditions evaluate different targets. Before changing a rule, confirm the actual destination of the request.
Policies and fallback
- PROXY
- Route through the selected proxy path
- DIRECT
- Connect directly to the destination
- REJECT
- Reject the request
- FINAL
- Set a policy for requests that haven't matched earlier rules
Write the policy after the condition. FINAL doesn't need a domain or IP range.
Put exceptions before broader conditions
Suppose you want to REJECT ads.example.com while routing other example.com domains through PROXY. Put the specific subdomain rule before the broader suffix rule. In the order shown in the previous code block, a request for ads.example.com would match the first line, DOMAIN-SUFFIX,example.com,PROXY, and the REJECT rule on the second line would never be checked. A rule that looks more specific won't jump ahead of earlier rules.
- In Config, open the configuration file you're currently using, find the section with the rule you want to change, and keep a copy of the original rule text for reference.
- Move the rule for
ads.example.comabove theexample.comsuffix rule. After saving, check the order shown in the list. - Leave Global Routing set to Config, start a new request to the destination, and check the in-app connection logs to confirm the destination and the policy actually used.
DOMAIN-SUFFIX,ads.example.com,REJECT
DOMAIN-SUFFIX,example.com,PROXY
GEOIP,CN,DIRECT
FINAL,PROXY
The same principle applies to IP ranges: if a smaller IP-CIDR range needs DIRECT while a larger range containing it needs PROXY, put the smaller range first. When changing the order, move only rules that actually overlap; don't reorder the entire configuration to fix a single domain. Test with a new request, too—an existing connection isn't a reliable way to verify the saved rule order.
How to check the order: find the first rule that could match
If the result doesn't match your expectations, scan down from the top for an earlier rule that also covers the destination. First correct its position relative to the rule you want, then consider changing the policy.
Why FINAL goes last
FINAL,PROXY routes requests that haven't matched any earlier rule through PROXY. Its job is to catch everything left over, not to give PROXY higher priority. Because FINAL doesn't specify a domain or IP range, placing it before rules you need to check prevents those later rules from matching. To connect unmatched requests directly, use FINAL,DIRECT if that fits your configuration. Neither option is universally better regardless of network conditions; what matters is deciding where unmatched traffic should go.
- Specific targets: List the domains or IP-CIDR ranges that need individual handling first. The clearer the overlap, the easier it is to verify rule order.
- Broader matches: Add general domain suffixes, GEOIP, and other conditions next. Check whether they match exceptions before those specific rules do.
- Last line: Use FINAL to handle the remaining requests. If you change the fallback policy, retest destinations without dedicated rules as well.
For example, with only DOMAIN-SUFFIX,example.com,DIRECT and FINAL,PROXY, requests matching that suffix use DIRECT, while unmatched requests use PROXY. If you add GEOIP,CN,DIRECT between them, the GEOIP rule handles only requests that match its condition and haven't already matched the domain rule. Describing the result line by line is more accurate than simply saying “mainland China direct, everything else proxy,” because earlier rules may also match.
Rules don't work as expected after saving: troubleshoot in order
First determine whether the rule wasn't applied or the selected route can't connect. To troubleshoot the first case, check Global Routing, the active configuration file, and earlier rules. For the second, check whether the selected proxy or direct route is available. Shadowrocket applies rules, but rules can't make an unreachable destination reachable. If you already have a provider and subscription, confirm that the configuration and connection details in use match what you're testing. You don't need to change subscription sources to troubleshoot.
- Go back to Home, confirm Global Routing is set to Config, and make sure you're editing the same configuration file that's currently in use.
- Check for possible matches from the first line down. Pay particular attention to broad DOMAIN-SUFFIX and IP-CIDR rules and to FINAL if they appear before the rule you're testing.
- Verify the actual domain or destination IP for the request. A webpage may request several domains, so an issue with the page doesn't necessarily mean the rule for its main domain failed to match.
- After saving your changes, start a new connection and check the in-app logs. If a matching PROXY rule still can't reach the destination, check the selected proxy and the destination's reachability separately.
I added REJECT. Why is the request still using PROXY?
Check from the top for an earlier DOMAIN-SUFFIX or FINAL rule that covers the destination. Move the specific REJECT rule above broader rules, save, and test again with a new request.
I changed FINAL. Why is a specific domain still routed the same way?
FINAL handles only requests that haven't matched an earlier rule. Find the first rule matching the domain before FINAL. To change its route, check that rule's policy or position.
I set GEOIP,CN,DIRECT. Why are some webpages still using PROXY?
First check the destination for that connection and the rules above GEOIP. GEOIP checks the destination IP's geolocation, not the language of the webpage. If an earlier domain rule matches, GEOIP isn't checked.
How can I test a rule after switching to Proxy?
Switch Global Routing on Home back to Config, confirm the active configuration file, and start a new request. Results with the global Proxy mode selected don't prove that a rule in Config matched.
If you're troubleshooting rules from a subscription, first check where you edited the local rules and what the configuration contains after a subscription update. An update may change the rules in use, so check that the target line is still present and correctly ordered before testing again. For PROXY policies, verify the rule match separately from the proxy connection status: a match only means the request was assigned to that route, not that the route was available at the time.