Shadowrocket Custom Rules: Matching Order, FINAL Fallback, and PROXY/DIRECT/REJECT

Learn how DOMAIN-SUFFIX, IP-CIDR, and GEOIP rules are evaluated, why FINAL belongs last, and when to use PROXY, DIRECT, or REJECT.

At a glance

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

Recommended

Requests 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.

3 types
Match conditions covered: DOMAIN-SUFFIX / IP-CIDR / GEOIP
3 strategies
Basic strategies covered: PROXY / DIRECT / REJECT
1 rule
The example uses one FINAL rule, placed at the end
KeywordExampleWhat it matches
DOMAIN-SUFFIXDOMAIN-SUFFIX,example.com,PROXYMatches example.com and its subdomains, but not notexample.com.
IP-CIDRIP-CIDR,192.168.1.0/24,DIRECT,no-resolveMatches the specified IPv4 range. no-resolve prevents this rule from triggering a DNS lookup solely for its own match.
GEOIPGEOIP,CN,DIRECTDetermines the IP address’s geographic location using an IP geolocation database, not the webpage language or domain suffix.
FINALFINAL,PROXYCatches 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.

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.

StrategyWhen to use itWhat to verify
PROXYThe 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.
DIRECTLocal 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.
REJECTA 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

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.

Verify the official App Store listing →