Custom rules determine which connection strategy handles a request. They’re useful if you’ve already configured your own service in Shadowrocket and want to adjust routing. First, check how Global Routing is set, then review rule syntax, exception order, and where FINAL belongs. Finally, save and test your changes. The fallback strategy depends on the active Config; examples here aren’t universal settings for every network.
Global Routing: Check whether rules are being applied
Global Routing controls the overall routing mode in Home; it isn’t the strategy for an individual rule. Shadowrocket custom rules generally apply to routing when Config is selected. Before editing, go to Home → Global Routing to check the current selection, then open Config and confirm which configuration is active. Use the option currently shown in the app as your reference; the rule checks in this guide assume Config is selected.
Config
RecommendedRequests are routed according to the rules in the active configuration. Selecting Config doesn’t mean every request uses PROXY; the result depends on the rule that actually matches.
Use for: Writing custom rules and testing domain exceptions and the final strategy.
Proxy
Sets overall routing to proxy mode instead of routing requests through the regular rules list described here. You can use it temporarily to compare access to the same destination through a proxy, then restore the original setting after testing.
Use for: Isolating the effect of rules and checking whether an existing proxy connection works.
Direct
Sets overall routing to direct mode. While this is selected, changes to regular routing rules don’t tell you whether those rules are working correctly.
Use for: Checking whether the current network can reach a destination directly.
Scene
Routing is controlled by configured scenes. When troubleshooting, check both the scene conditions and their associated actions; the rule text in a single configuration file may not tell the whole story.
Use for: Switching routing based on the environment when scene conditions are already configured.
On Demand controls when a connection is triggered; it doesn’t replace rules such as DOMAIN-SUFFIX. If a connection comes back after you disconnect, check the current conditions in Settings → On Demand. If the connection is already active but requests are routed incorrectly, start by checking Global Routing, the active Config, and the matching rule. Troubleshoot these as separate issues.
Rule syntax: Separate match conditions from actions
A rule consists of a rule type, a value to match, and a strategy. The common format is type,value,strategy. FINAL has no match value; it specifies only the fallback strategy. When editing plain text, use standard ASCII commas. Don’t include a URL’s scheme, path, or query parameters in a domain match value. The examples below belong in the configuration file’s [Rule] section, not in the server address field in Home.
| Keyword | Example | What it matches |
|---|---|---|
DOMAIN-SUFFIX | DOMAIN-SUFFIX,example.com,PROXY | Matches example.com and its subdomains, but not notexample.com. |
IP-CIDR | IP-CIDR,192.168.1.0/24,DIRECT,no-resolve | Matches the specified IPv4 range. no-resolve prevents this rule from triggering a DNS lookup solely for its own match. |
GEOIP | GEOIP,CN,DIRECT | Determines the IP address’s geographic location using an IP geolocation database, not the webpage language or domain suffix. |
FINAL | FINAL,PROXY | Catches requests that didn’t match any earlier rule and applies the specified strategy. |
In IP-CIDR, /24 is the network prefix length. The example covers 192.168.1.0 through 192.168.1.255. To match a single IPv4 address, use /32. These numbers aren’t server ports; domain rules shouldn’t use a value like example.com:443 either. Matching requests by port is a different requirement and can’t be achieved by changing the DOMAIN-SUFFIX match value.
Rule order: Put specific exceptions before broader matches
Rule order determines the sequence in which rules are checked; the system doesn’t automatically choose the “most specific match.” In typical rule-based routing, once a request matches a valid rule, that rule’s strategy applies, and later regular rules don’t override it. Put specific domain exceptions before broader domain matches, position network and geographic rules where appropriate, and keep FINAL at the end.
[Rule]
DOMAIN,api.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
IP-CIDR,192.168.1.0/24,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY
This snippet illustrates rule order: api.example.com matches the first rule and uses DIRECT; www.example.com matches the second and uses PROXY; direct access to 192.168.1.20 is handled by the IP range rule. Whether other requests match GEOIP depends on the destination address and database results. Requests fall through to FINAL only if none of the earlier rules match. example.com is used for illustration and doesn’t represent a usable service.
- If you move
DOMAIN-SUFFIX,example.com,PROXYabove the exact-domain rule, it will match api.example.com first, making the later DIRECT exception ineffective. - If you put
GEOIP,CN,DIRECTbefore some domain exceptions, it may match the geographic condition first when the destination IP is available. Put domains with a specific routing requirement first. - Putting
FINAL,PROXYin the middle means regular rules after it can’t serve their intended matching purpose. Add new rules before FINAL. - If the same domain appears more than once with different strategies, the first matching rule determines the result. When troubleshooting, search the entire rule section, not just the line you’ve just added.
PROXY, DIRECT, REJECT: Choose a strategy for each destination
A strategy describes what happens after a rule matches, not what the rule matches. PROXY sends the request through the proxy route, DIRECT connects over the current network, and REJECT blocks the request. The default final strategy depends on the active Config. Decide how you want unclassified traffic handled before choosing FINAL; don’t replace it across the board without testing.
| Strategy | When to use it | What to verify |
|---|---|---|
PROXY | The destination is known to require access through a proxy service you already have. | Check the currently selected service or policy group and its connection status. A rule match doesn’t guarantee a successful remote connection. |
DIRECT | Local network devices or destinations confirmed to be reachable directly over the current network. | Check local routing, network permissions, and the destination service itself. DIRECT still requires working DNS and network connectivity. |
REJECT | A destination you explicitly don’t want to connect to, after confirming the impact of blocking it. | Test with a precise DOMAIN match first to avoid accidentally blocking public domains required for sign-in, payments, or page functionality. |
FINAL,PROXY sends unclassified requests through a proxy. Use it when you explicitly want to keep that fallback behavior. FINAL,DIRECT connects unclassified requests directly and may suit a configuration that already lists the destinations that should use a proxy. Neither is universally better; it depends on what you’re trying to do. Setting FINAL to REJECT blocks every request not listed above, potentially breaking newly encountered domains, so it’s not a good starting point for writing rules.
DOMAIN,blocked.example.com,REJECT
DOMAIN,printer.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
FINAL,DIRECT
The example shows strategy exceptions within the same domain range; it isn’t a ready-to-use routing setup. For PROXY, also check the currently selected service and the policy name referenced in the configuration. If a rule uses a custom policy group, its name must match the one defined in the configuration. Don’t confuse Proxy mode in Global Routing with PROXY in a rule; they’re settings at different levels.
Save and test: Change one thing at a time
Testing means connecting what you edited with the currently active file and the results of actual requests. Before you start, keep a copy of the original file in Config and note the current Global Routing selection. This guide assumes you already have your own service and subscription and are only changing routing rules. Updating Subscribe in Home and updating a Config file affect different things; refreshing a server subscription doesn’t necessarily replace the rules currently in use.
-
Check the routing mode
Go to Home → Global Routing → Config. Note the service currently selected in Home. Avoid changing both the rules and the service at once, or you won’t be able to compare the results.
-
Find the configuration file
Open Config and confirm which configuration is selected. Open its editing view and check the Rule list or the
[Rule]section in plain text. The labels for editing options can vary; follow what’s currently shown in the app. -
Add an exception
Insert a rule for a specific destination before broader rules and before FINAL. If you’re editing plain text, modify the existing
[Rule]section; don’t paste the example twice and create duplicate rule sections. -
Save and apply
After saving, return to Config and make sure the edited file is still selected, then go back to Home. If needed, disconnect and reconnect to test with a new request. Existing long-lived connections aren’t a reliable way to tell whether a change has taken effect.
-
Check the request
Visit the destination again, then check the request log in the app for the destination domain or IP, the strategy used, and any available rule details. For further diagnostics, see Settings → Log. The fields shown depend on the current interface.
A useful test record includes at least the destination, the expected strategy, and the actual strategy. For example, for a destination you control, note: “Expected DIRECT from the exact-domain rule; the log shows DIRECT.” If the result is PROXY, first check the active file and the broader rules above it; don’t immediately change DNS. The walkthrough here is illustrative, not a live network test, and doesn’t provide a reachable test service.
DNS and address rules: Don’t mistake a resolution issue for an ordering issue
DNS translates domain names into addresses, while IP-CIDR and GEOIP need address information to evaluate a match. DOMAIN-SUFFIX primarily matches domain names; IP-CIDR checks an address range. Whether a request includes a domain, whether it has already been resolved, and the configuration’s DNS options and cache state can all affect what you see while troubleshooting. You can’t tell which rule matched just by checking whether a webpage loads.
- Limits of no-resolve:
IP-CIDR,192.168.1.0/24,DIRECT,no-resolvewon’t actively resolve a domain solely to match this rule. It doesn’t disable DNS globally or guarantee that other rules won’t trigger a lookup. - Limits of GEOIP: Geographic results depend on the destination IP and the database. Two sites in the same language can be associated with different regions, and different IP addresses for the same domain can have different locations.
- Limits of IPv6: The
IP-CIDRexample is an IPv4 range rule; it doesn’t cover IPv6. If the connection uses IPv6, check the relevant address rules and configuration support separately. - Limits of caching: Browser cache and existing connections can prevent a request from being made again as expected. After changing rules, make a new test request and reconnect if needed before checking the result.
A good troubleshooting order is to check the routing mode and active file first, then identify the matching rule, and finally check address resolution and service connectivity. If the request log already shows the expected strategy but the destination is still unavailable, the issue may involve DNS, the remote service, TLS, or the current network path. Changing FINAL’s position usually won’t fix a connection failure.
FAQ: Rules not taking effect and changes being overwritten
I added a rule, so why is everything still going through the proxy?
First, go to Home → Global Routing and check that Config—not Proxy—is selected. Then confirm the active file in Config. If both are correct, check whether the destination matches a DOMAIN-SUFFIX rule or another broad rule above your new one. Move the specific exception above it, save, and make a new request.
Can rules after FINAL still take effect?
For the regular rule list discussed here, don’t rely on rules after FINAL. Move all match conditions above FINAL and keep just one explicit final strategy. When checking for duplicate FINAL rules, search the whole rule section, not just the last few lines of the file.
Why did my custom rules disappear after a subscription update?
First, identify what was updated: Subscribe in Home typically updates server information, while updating a remote Config can replace its contents. Open Config to check whether the active file was updated or switched. To preserve local changes, save a separate copy and compare the rule section after each update.
The website’s home page loads, but sign-in fails. Should I change FINAL?
First, check which new domains appear during sign-in and which strategies they actually use. Sign-in may use a separate domain, or a domain may be blocked by REJECT or routed through a different exit. Add exceptions only for relevant domains you’ve confirmed, and put them before broader rules. Don’t switch the entire rule set to DIRECT or PROXY.
Rule maintenance is complete when the results are explainable and changes can be rolled back: every exception has a clear target, each test identifies the matching rule, and FINAL handles requests as expected. If you still can’t explain the result, restore the backup and add rules one at a time instead of combining multiple configuration snippets from different sources. For more interface guidance, see the Options Manual.