In Shadowrocket, rule priority is determined by position—not by domain length or policy name. This guide is for users who already have their own provider and subscription and want to adjust traffic routing. First, check Global Routing on Home. Then verify the active configuration in Config, place specific exceptions before broad rules, and test FINAL with a new connection.
Set Global Routing to Config first
Before editing rules, distinguish between whether you are connected and how traffic is routed. The connection toggle on Home enables the connection; Global Routing determines how requests are handled. To test rules in a configuration file, set Global Routing to Config, then open Config and confirm which file is active. Editing a file that is not in use will not change routing behavior.
In Global Routing, Proxy applies proxy handling globally, while Direct sends traffic direct. Neither confirms that a rule in a configuration file matched. Scene applies settings for a particular scenario; it is not a fixed Config state. When troubleshooting an individual rule, select Config first to avoid interference from switching scenes.
Bottom line: Fix the mode before editing rules
If traffic behavior does not change after editing rules, do not start by adding another rule. Go back to Home to check Global Routing, then check in Config which file is actually active.
Rules are checked top to bottom—not auto-sorted by specificity
Think of the rule section as an ordered list of conditions. When a request is routed, the app checks each rule in sequence. As soon as one matches, its policy is applied; later rules are not considered, even if they seem like a better fit. Put specific exceptions before general rules rather than relying on the app to rank conditions by how specific they are.
This example shows a common ordering issue. DOMAIN-SUFFIX,example.com,PROXY matches example.com and all its subdomains. For a request to api.example.com, the first line already matches, so the exact-domain rule below it never gets checked.
[Rule]
DOMAIN-SUFFIX,example.com,PROXY
DOMAIN,api.example.com,DIRECT
FINAL,PROXY
If the goal is to send this subdomain direct while proxying other domains with the same suffix, put the exception first. The domain here is only an example to explain the syntax; it does not provide a connection service or test availability.
[Rule]
DOMAIN,api.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
FINAL,PROXY
The same principle applies to blocking exceptions. To reject only one subdomain while allowing other requests under the same suffix to use the proxy, place the exact REJECT rule before the broader suffix rule. A REJECT policy is not inherently higher priority just because it seems more restrictive.
How to order DOMAIN-SUFFIX, IP-CIDR, and GEOIP
These keywords describe different matching conditions; they are not fixed priority levels. DOMAIN-SUFFIX checks a domain suffix, IP-CIDR checks whether the destination IP falls within a specified range, and GEOIP matches a region code using IP geolocation data. Order rules by putting specific exceptions first, followed by broader address or region rules.
Domain condition
- DOMAIN
- api.example.com,DIRECT
- DOMAIN-SUFFIX
- example.com,PROXY
- Matches against
- Domain information for the request
Put exact exceptions first, followed by suffix-wide rules.
Address condition
- IP-CIDR
- 192.168.0.0/16,DIRECT,no-resolve
- GEOIP
- CN,DIRECT
- Matches against
- Destination IP and local geolocation data
Specific IP ranges usually go before broad regional rules.
IP rules need a destination IP to evaluate. If a request starts with a domain name, the resolution process can affect whether IP-CIDR or GEOIP can match. In the example, no-resolve means not to trigger domain resolution solely for this rule. It does not disable DNS for the entire app or mean that every domain request can match the IP range directly.
- For a specific domain exception: Put DOMAIN or DOMAIN-SUFFIX first so the request gets a defined policy before reaching a broad IP condition.
- For a defined local network range: Use IP-CIDR for your actual network.
192.168.0.0/16is one private address range; it does not cover every local network. - For a general policy by region: Put GEOIP after specific exceptions. Geolocation data describes an IP's registered location, not a website's language or its domain suffix.
- For requests that match no conditions: Let FINAL at the end of the rule section handle them. Do not insert an unconditional rule earlier.
GEOIP results depend on the geolocation data used by the app and may not match the website operator's location. Websites using a CDN may also resolve to different IP addresses at different times. If a domain needs a consistent policy, write a rule for that domain rather than relying on GEOIP to determine its route.
PROXY, DIRECT, and REJECT are actions, not priority levels
A rule typically consists of a keyword, a match value, and a policy. For example, in DOMAIN-SUFFIX,example.com,PROXY, the first two parts specify what to match, and the last specifies what to do when it matches. FINAL is a special catch-all rule with no domain or IP range, so it is written as FINAL,PROXY.
| Policy | What happens on a match | What to check |
|---|---|---|
PROXY |
Routes traffic through the proxy configured for the current setup | Check the selected server or policy group, and confirm the service is available |
DIRECT |
Connects directly to the destination without a proxy server | Check whether the current network can reach the destination directly |
REJECT |
Rejects the matching request | Check whether a login, image, or API domain was blocked by mistake |
A PROXY match only means the rule selected proxy handling; it does not guarantee that the destination is reachable. An unavailable server, an issue with the destination service, or a resolution failure can still prevent access. A DIRECT match does not mean the request skipped all rule checks; it means the request uses a direct connection after rule evaluation.
If your configuration uses a custom policy group name, the rule's final field must match an existing name exactly. Do not use arbitrary explanatory text as a policy, and do not assume the current route is correct just because the rule says PROXY. Also check the selection on Home and the state of the relevant policy group in the configuration.
Why FINAL goes last, and whether to use PROXY or DIRECT
FINAL does not target a particular domain, IP range, or region. It handles the remaining requests that reach it. Placing it near the start of the rule section prevents later rules from being checked. When maintaining a configuration, check the catch-all at the end instead of repeatedly adding FINAL whenever something goes wrong.
[Rule]
DOMAIN,api.example.com,DIRECT
DOMAIN,blocked.example.com,REJECT
DOMAIN-SUFFIX,example.com,PROXY
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY
This example demonstrates rule order; it is not a complete configuration file. Keep other required sections in your existing configuration and merge rules according to your needs. Do not replace the entire file with these lines. The first subdomain in the example uses DIRECT, the second uses REJECT, and other domains with the same suffix use PROXY. Remaining requests are then evaluated against address rules, region rules, and the final catch-all in that order.
- Choose FINAL,PROXY: Requests that do not match a specific exception will also use the proxy. This fits configurations where all uncategorized requests should use the proxy route.
- Choose FINAL,DIRECT: Only requests explicitly assigned to the proxy above will use it; all others connect directly. Keep in mind that destinations not covered by your rules may not be reachable directly.
- Back up before making changes: Keep a working copy of the current configuration and note its FINAL policy. If the changes affect more traffic than expected, restore the original file instead of adding more exceptions.
Bottom line: Decide how uncategorized requests should be routed
When checking FINAL, first decide where requests that match no known rules should go, then choose PROXY or DIRECT. Do not treat the catch-all policy as a switch that fixes every connection problem.
How to verify changes without mistaking cached connections for new results
Treat a rule change as a complete process: save it, confirm it is active, start a new connection, and check the records. Browsers and apps may reuse existing connections, so revisiting a page does not necessarily trigger the same rule evaluation again. Distinguish an existing connection continuing from the result of a new request.
- Back up the current file: In Config, confirm which configuration is active. Keep a copy of it before editing, and note the specific domain or IP range you plan to change.
- Change one variable at a time: For example, move only the DOMAIN exception above DOMAIN-SUFFIX. Do not change DNS, servers, and FINAL at the same time.
- Save and confirm the change is active: After editing, make sure the target file is still the active configuration. Go to Home and confirm Global Routing is set to Config and the connection is working.
- Start a new connection: Close the existing connection for the page or app and try again. If needed, reconnect during a brief interruption, then visit the destination again.
- Check connection records: In Data, review available connection records or logs for the destination domain, destination IP, and policy. If the records include rule details, check which specific rule matched.
For example, if api.example.com is expected to match DIRECT but the records show that it used PROXY via a suffix rule, first check the rule order and whether the file is active. If the records show DIRECT but access still fails, investigate direct reachability instead of copying the same rule higher in the list.
Keep updates to existing server subscriptions separate from configuration file updates. A change to the server list does not necessarily change rules in Config, while a remote configuration update may overwrite local edits. Confirm which item you are editing, then check rule order and FINAL again after an update to determine whether the issue is matching or overwritten content.
Frequently asked questions about rule priority
Why isn't my more specific rule taking effect?
Shadowrocket does not automatically move more specific rules to the top. In Config, check the actual rule order and move the DOMAIN exception above any DOMAIN-SUFFIX rule that would match first. Save the change and start a new connection. Also confirm that the file is active and Global Routing is set to Config.
Why are some requests still going direct after I changed FINAL to PROXY?
FINAL only handles requests that did not match an earlier rule. Check whether the destination already matched a DIRECT rule above it, such as DOMAIN, IP-CIDR, or GEOIP. A request that has already matched will not be reassigned by FINAL.
Can GEOIP,CN,DIRECT override an earlier domain proxy rule?
No. If a request matches an earlier DOMAIN-SUFFIX proxy rule, evaluation stops there. GEOIP only handles requests that have not matched a preceding rule. If the result differs from what you expect, check the actual request domain, the active file, and the match details in the records.
A page only partly loads after I added REJECT. How can I fix it?
First restore the REJECT rule you just added, then reload the page to check whether it works again. A page may request several domains for logins, APIs, images, and more. Once you identify the domain blocked by mistake, narrow the match condition. If needed, put a specific allow exception before the broader REJECT rule.
My custom rules disappear after every configuration update. What should I do?
First determine whether the update changed a server subscription or a remote configuration file. If the remote file overwrote your local edits, keep a separate configuration copy you can maintain and compare it with future updates to preserve the rules you need. Repeatedly pasting rules is not a reliable fix; duplicate entries can also change the effective order.