Shadowrocket Rule Syntax Guide: DOMAIN-SUFFIX, GEOIP, IP-CIDR & FINAL

Learn what DOMAIN, DOMAIN-SUFFIX, DOMAIN-KEYWORD, GEOIP, IP-CIDR, and FINAL match, how rules are evaluated in order, and how to use PROXY, DIRECT, and REJECT.

At a glance

Shadowrocket rules determine which policy a connection uses; they don’t provide servers. This guide is for users who have already imported a server and are ready to route traffic with Config. First, distinguish Global Routing from the configuration file; then learn six rule keywords and use a minimal example to check match order, DNS conditions, and outbound behavior. Domain and address examples are for explaining syntax only and aren’t usable server details.

1. Select Config before checking whether rules apply

Shadowrocket rules aren’t necessarily evaluated one by one as soon as a connection opens. On Home, check Global Routing: select Config to use the rules in the active configuration. Also check Config to make sure the file you edited is the one in use—not a different file with the same name.

OptionPurposeWhat to check when testing rules
ConfigRoute traffic using the current configurationRequired to verify the rule examples in this guide.
ProxyUse a proxy for all outbound trafficYou can’t use this mode to verify whether a rule selects DIRECT.
DirectConnect directly for all trafficYou can’t use this mode to check whether a PROXY rule works.
SceneApply settings based on the active sceneCheck the active scene first so a scene change isn’t mistaken for a rule failure.

Home is where you select a server and connect; Config manages configuration files; Settings contains app settings. Settings → On Demand affects when connections are made. It doesn’t automatically change a DOMAIN-SUFFIX rule’s policy. When troubleshooting, distinguish whether a connection is established from which rule it follows once established. Avoid changing both types of settings at the same time.

2. Rules are evaluated top to bottom; the first match wins

A typical rule uses English commas to separate three fields: rule type, match value, and policy. FINAL has no match value, so its format is “FINAL,policy.” Rules are checked in order. Once one matches, its policy applies and later rules aren’t checked—even if they seem more specific. That’s why a configuration should put specific exceptions first, broader matches later, and FINAL last.

Connection detailsCheck each ruleFirst matchSelect a policyRoute traffic
DOMAIN,api.example.com,PROXY
DOMAIN-SUFFIX,example.com,DIRECT
FINAL,PROXY

In these three lines, api.example.com matches the first rule and uses PROXY. www.example.com doesn’t match the first rule, but does match the second, so it uses DIRECT. If you move the second rule above the first, the suffix rule will also catch api.example.com first, preventing the specific exception from taking effect. An incorrect order may not trigger a syntax error, but it changes the result.

3. Understanding DOMAIN, DOMAIN-SUFFIX, and DOMAIN-KEYWORD

Domain rules match domain information available for a connection, not a full web address. Don’t include a scheme, port, path, or query string in the match value. For example, when visiting a page with the path /account, DOMAIN still checks only the hostname; it can’t distinguish between two pages on the same host.

Keyword and exampleMatchesDoesn’t match / notes
DOMAIN,example.com,DIRECTexample.comDoesn’t include www.example.com.
DOMAIN-SUFFIX,example.com,PROXYexample.com、www.example.com、a.b.example.comDoesn’t include notexample.com; suffix matching respects domain label boundaries.
DOMAIN-KEYWORD,metrics,REJECTConnections to domains containing metricsThe match can be broad; it doesn’t only match a subdomain named metrics.

To proxy only api.example.com, use DOMAIN rather than DOMAIN-KEYWORD with api. The keyword rule could also match unrelated domains. Use DOMAIN-SUFFIX when you need to cover a domain and all its subdomains. Don’t use the wildcard *.example.com in place of the suffix syntax shown here.

4. How IP-CIDR, GEOIP, and DNS relate

IP-CIDR matches an address range; GEOIP matches based on the location assigned to an IP address in a geolocation database. Both use address information—not a page’s language, an account’s region, or a country-code top-level domain. A domain’s suffix alone can’t tell you which GEOIP region it will match.

IP-CIDR,192.0.2.0/24,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY

192.0.2.0/24 is a documentation-only example range. /24 means the first 24 bits are the network prefix, covering 192.0.2.0 through 192.0.2.255; it isn’t a usable server address. IP-CIDR matches the entire address range, not just the text 192.0.2.0. For IPv6 ranges, use the corresponding IP-CIDR6 rule type; don’t put an IPv6 address into an IPv4 example.

When domain rules don’t match and a later IP rule needs address information, DNS state may affect the matching process. GEOIP results also depend on the actual destination address and the database, so they can’t be relied on to cover every resource used by a type of website. When troubleshooting, record the specific domain, actual address, and matched policy—not just that an app “won’t open.”

5. Understand FINAL and policy results with a minimal rule set

The complete rule block below is for reading and testing, not a recommended configuration for every network. Keep your full configuration and server settings, and make changes only in a copy. Don’t treat a snippet containing only [Rule] as a new configuration with all connection settings included.

[Rule]
DOMAIN,blocked.example.com,REJECT
DOMAIN,api.example.com,PROXY
DOMAIN-SUFFIX,example.com,DIRECT
DOMAIN-KEYWORD,metrics,REJECT
IP-CIDR,192.0.2.0/24,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY

To reject metrics.example.com as well, add an exact DOMAIN exception before the suffix rule. If you move the entire keyword rule higher, every domain containing metrics could be rejected earlier. Before changing the order, define the scope you need and choose between adding an exact exception and moving a broad rule. This avoids expanding the impact just to fix one domain.

6. Edit and verify rules in the active configuration

  1. Keep a copy of the original configuration

    Open Config and make a copy of the working configuration before editing. Then open the file you want to change. Note the filename and current Global Routing setting so you can revert if needed.

  2. Check the rule section

    Find [Rule] in the configuration text and edit one line at a time, using English commas. Put specific exceptions before the relevant broad rules and FINAL last. Don’t paste multiple [Rule] sections as a substitute for putting rules in order.

  3. Save and select the mode

    After saving, confirm in Config that this file is in use. Then go to Home → Global Routing → Config. Saving a file without selecting it won’t verify your changes.

  4. Check outbound connectivity

    On Home, select an existing server and run Connectivity Test to confirm that a proxy connection is possible. Get server and subscription details from your service provider; rule text can’t replace those settings.

  5. Test a new connection

    Make the target request again, then check the app’s connection log for the destination, matched rule, and outbound policy. Change one thing at a time. Existing connections may be reused, so stop the old request and reconnect before testing again if needed.

Connectivity Test checks whether a connection can be made; by itself, it can’t prove that a website matched a particular rule. Use the log for the specific request to verify rule matching. Also distinguish server subscriptions from rule configuration: updating the server list on Home doesn’t update rules in the active Config. After refreshing a remote configuration, check whether your local changes were retained.

7. Tell rule errors apart from outbound connection errors

If a rule matches PROXY but a page still won’t load, that doesn’t necessarily mean the syntax is wrong. Here are common network error snippets from connection logs. Full error messages may include an address, port, and lower-level details. First check whether the error occurred while connecting to the destination or to the proxy server.

Error: connection refused

Cause and fix: The connection endpoint refused the connection. This often means the destination port isn’t listening or the connection was actively rejected. Check the failed endpoint in the connection log, then verify the relevant server or destination address and port. Moving FINAL alone won’t fix it.

Error: i/o timeout

Cause and fix: The network operation didn’t finish before the timeout. First, use Connectivity Test on Home to check the selected server. Then check whether the request actually used DIRECT or PROXY and troubleshoot the corresponding direct or proxy route.

For example, if your provider specifies server port 443, check that the server settings also use port 443. Don’t replace an existing port just because 443 appears in a rule example. DOMAIN-SUFFIX has no port field; a server’s listening port and a domain match condition are separate things.

8. Common questions about rule configuration

Why is traffic using a different policy even though I added a DOMAIN rule?

On Home, go to Global Routing and make sure Config is selected. Then check Config to confirm which file is active. Review every rule above yours, especially earlier DOMAIN-SUFFIX, DOMAIN-KEYWORD, and FINAL rules. A connection already matched by an earlier rule won’t be checked against later ones.

Can GEOIP,CN,DIRECT replace all domain rules?

No. GEOIP uses the database location for the destination IP, and the same service may use resources in different regions. To set a consistent policy for a specific domain, put an explicit DOMAIN or DOMAIN-SUFFIX rule before GEOIP, then verify it in the connection log.

Why are my rules still old after refreshing a subscription?

First, confirm what was updated. Refreshing a server subscription on Home mainly updates server entries; rules come from the active Config. In Config, check the actual configuration contents and whether the file is active. A change in server names doesn’t prove the rules were updated.

Will changing FINAL to DIRECT fix my connection?

That only changes the fallback route for connections that didn’t match an earlier rule; it won’t fix server settings or DNS issues. First confirm that the destination actually matched FINAL. If only one domain needs an exception, add a rule with a clearly defined scope instead of changing the route for all unmatched connections.

Get Shadowrocket on the App StoreVerify the developer and app ID