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

Rules are evaluated one at a time from top to bottom. Evaluation stops at the first match. This guide covers rules such as DOMAIN-SUFFIX and IP-CIDR, how FINAL works as a fallback, and when to choose PROXY, DIRECT, or REJECT.

At a glance

Custom rules work only when the correct configuration is enabled and Global Routing is set to Config. This guide is for users who have already imported their own server details and want to adjust routing: distinguish the routing mode from rule policies, place specific exceptions before broader matches and FINAL last, then check the results with a new connection. Example domains illustrate syntax; they are not service addresses.

1. Check Global Routing before troubleshooting rules

In Shadowrocket, server selection, configuration files, and global routing are separate settings. Selecting a server in Home does not mean every request will use the proxy; having rules in Config does not mean the current routing mode is using them. To troubleshoot, go to Home → Global Routing and check the current selection.

To route traffic using the rules in this guide, select Config. Proxy and Direct are useful for comparison, but their connection results do not show whether a specific configuration rule matched. Scene provides scenario-based routing. If you are using Scene, check its current settings rather than assuming it is equivalent to the Config test described here.

Config: Route by Configuration

Recommended

Requests follow the policies in the active configuration. All rule-order and FINAL examples in this guide assume this routing mode.

Use for: Everyday rule-based routing and testing custom rules

Proxy: Global Proxy

Routes connections handled by the client through the proxy. Use this to check whether an existing server can carry a connection to the target, not to test the order of rules in your routing list.

Use for: Temporary comparison and distinguishing proxy connection issues from rule issues

Direct: Global Direct

Connects directly to the destination for connections handled by the client. A website opening in this mode does not prove that a PROXY rule in the configuration is working.

Use for: Checking direct access over your local network

2. Rules run from top to bottom; they are not automatically sorted by specificity

A rule list is an ordered set of checks, not a collection automatically sorted by how specific each rule is. Once a request matches an earlier rule, later standard rules are not considered. “A full domain is more specific than a suffix” is a principle for arranging rules, not a promise that the app will adjust their priority for you.

[Rule]
DOMAIN,api.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
FINAL,DIRECT

In this example, a request to api.example.com matches the first line and uses DIRECT. www.example.com does not match the first line, but it matches the second and uses PROXY. Requests that match neither condition fall through to FINAL. Here, [Rule] is the section header in a text configuration; it is not content to repeat before every rule.

First match wins
The list order determines the policy; specific rules are not automatically moved to the top
3 policies
This guide uses PROXY / DIRECT / REJECT
1 rule at the end
The examples use a single FINAL rule as the fallback

3. What DOMAIN-SUFFIX, IP-CIDR, and GEOIP match

A standard condition rule is usually written as “rule type,match value,policy,” with English commas as separators. The domain field takes a hostname only, not https://, a path, or query parameters. For example, /account in a URL is not matched by DOMAIN-SUFFIX; these rules are not web content filters either.

KeywordExample syntaxWhat it matches
DOMAINDOMAIN,api.example.com,DIRECTMatches an exact hostname, not its subdomains.
DOMAIN-SUFFIXDOMAIN-SUFFIX,example.com,PROXYMatches example.com and its subdomains, not any domain that happens to contain this string.
IP-CIDRIP-CIDR,192.168.0.0/16,DIRECT,no-resolveMatches an IPv4 address range; this example covers 192.168.0.0 through 192.168.255.255.
GEOIPGEOIP,CN,DIRECTUses a geolocation database to check the destination IP, not the page language or domain suffix.
FINALFINAL,PROXYTakes no match value and catches requests that did not match earlier rules.

no-resolve is an option, not a policy name. On an IP rule, it means not to actively resolve a domain to an IP for the purpose of matching that rule. If the request already targets an IP, the address range can still be checked. So if an IP rule with this option does not match a domain request, that alone does not mean the address range is wrong.

4. How to combine PROXY, DIRECT, REJECT, and FINAL

PROXY sends matching requests through the proxy path; DIRECT connects to the destination directly; REJECT blocks matching requests. PROXY in a rule does not create a server or provide connection credentials. Before using it, import your own server or subscription and confirm that the selected proxy path works. This site does not provide, sell, or recommend nodes, subscriptions, or providers.

FINAL is a fallback; it does not mean “force this policy for every request.” It applies only when no earlier rule matches. To send unmatched requests through the proxy, use FINAL,PROXY. To connect unmatched requests directly, use FINAL,DIRECT. These are different routing choices, and neither is right for every network.

[Rule]
DOMAIN,api.example.com,DIRECT
DOMAIN-SUFFIX,blocked.example.com,REJECT
DOMAIN-SUFFIX,example.com,PROXY
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
FINAL,DIRECT

This configuration demonstrates four outcomes: a specified API connects directly, a specified subdomain range is rejected, other example domains use the proxy, and unmatched requests connect directly. The REJECT rule for blocked.example.com must go before the proxy rule for all of example.com; otherwise, the broader suffix rule will match first. This is a minimal teaching example, not a complete configuration for every use case.

Why not add two FINAL rules at the end?
The first FINAL already catches the remaining requests, so a later one cannot offer a second choice. A proxy failure does not make a request continue to another FINAL rule. For failure handling, check the proxy or policy group settings instead of adding a duplicate fallback.

5. Edit rules in Config and test with a new connection

Back up your current configuration before changing a small set of rules with clear, observable results. The steps below refer to the mobile Home / Config interface; editing options may look different across platforms. Always check which file you are editing, which file is enabled, and which routing mode Global Routing is using. Do not confuse updating a server subscription with editing a rule file.

  1. Back up the configuration

    Open Config, confirm which configuration file is enabled, and save a copy or export a backup first. Downloading a remote configuration again may overwrite local edits, so keep a recoverable version before testing.

  2. Edit the rules

    From Config, open the rule editor for that file. If editing as plain text, find [Rule]. Put specific exceptions before broader rules and check the FINAL at the end of the list. Do not paste the section header again inside an existing rule section.

  3. Check the routing mode

    Save the changes and confirm that the configuration is enabled, then go to Home → Global Routing → Config. In Home, also confirm that your own working server is selected before connecting.

  4. Start a new connection

    Close the existing test page or app connection, then revisit a target you are authorized to test. Existing long-lived connections may keep using the previous route, so refreshing a page that reuses its connection is not enough to determine whether the change worked.

  5. Check the connection log

    Open the connection log, find the new request by hostname or IP, and check the policy applied and any visible rule details. Change one rule position at a time and note the results before and after to avoid changing multiple variables at once.

For example, temporarily add an exact REJECT rule for a test domain you control and place it before the relevant suffix rule. A new connection should then be rejected. Restore the rule to DIRECT and check whether a direct connection succeeds. Use the connection log to verify the result: cached pages may still show old content after a request is rejected, and third-party resources on the page may use entirely different domains.

6. Common custom rule issues and how to troubleshoot them

Rules are saved, but traffic still uses the proxy. Why?

First check whether Home → Global Routing is still set to Proxy, then return to Config and confirm that you edited the active file. If both are correct, scan from the top of the rules for an earlier suffix rule, IP range rule, or other match that may have caught the request. Do not check only the line you just added.

Why does some traffic still use PROXY after I change FINAL to DIRECT?

FINAL handles unmatched requests only. Check whether the destination already matches an earlier DOMAIN or DOMAIN-SUFFIX rule. To connect a single domain directly, place an exact-domain DIRECT exception before the relevant broader rule. Reconnect before checking the result.

Why does part of a page still load when I use REJECT?

First rule out cached content and existing connections, then check the hostname that actually made the request. A page may use separate domains for the main site, images, APIs, and static assets. Rejecting one domain does not automatically cover all related domains. Add rules based on the connection log; do not reject an entire address range without checking.

Why did the results change after updating a subscription?

Identify what was updated: a server subscription update may change server entries and the current selection, while a remote configuration update may change the rules. Check the selected server in Home, then check the active file and rule order in Config. Compare with your backup first; do not assume every issue is caused by FINAL.

A rule matched PROXY, but the connection still fails. What should I do?

A match confirms the routing choice, not that the remote connection succeeded. Check your existing server settings, current network, and the target service status. You can also temporarily select Global Routing → Proxy to test the same target for comparison. If both routing modes fail, investigate the connection path instead of adding duplicate rules.

Use this checklist in order: check the routing mode, check the active configuration, find the first matching rule, then check the proxy or destination connection. This separates “rules are not being used,” “rule order is wrong,” and “the policy is correct but the connection failed,” so you can avoid repeatedly changing the same FINAL rule.

Download Shadowrocket