Shadowrocket REJECT Rules: How Blocking Works, Matching Scope, and Limitations

Learn how rules are matched from top to bottom, when REJECT blocks domain requests, what it cannot block, and how to troubleshoot false positives.

At a glance

This guide is for Shadowrocket users with a working configuration who want to adjust blocking rules. Start by checking Global Routing on Home, then inspect the active configuration’s [Rule] section in Config: use DOMAIN for an exact match and DOMAIN-SUFFIX to cover subdomains. Put exceptions before blocking rules, then verify the results in request logs. The domains and addresses shown are syntax examples only, not working services.

Check Home and Config first: where REJECT takes effect

Check Global Routing on Home. For the rule checks in this guide, select Config, then confirm the active configuration in Config. Open its editor and inspect the [Rule] section. Adding rules to a file that is not active will not change how current connections are handled. Likewise, if the connection toggle on Home is off, browsing results cannot confirm whether the rules are working.

REJECT is the policy applied when a rule matches; it is not a rule type or a server name. A rule first checks whether a request meets its conditions, and only then applies the rejection policy. It does not send the request to a proxy server before rejecting it, nor does it delete content already stored locally on a webpage.

Where to check

Home
Make sure the connection is on
Global Routing
Select Config
Config
Confirm the edited configuration is active
[Rule]
Check rule order and the final policy

First confirm the configuration is handling requests, then check whether the rules themselves are correct.

Global Routing modes

Config
Route traffic according to the active configuration’s rules
Proxy
Global proxy; not suitable for verifying the rules in this guide
Direct
Global direct; not suitable for verifying the rules in this guide
Scene
Routing depends on the active Scene; check its settings separately

Keep Config selected while troubleshooting to avoid Scene changes affecting the test.

Settings → On Demand controls when connections are established or disconnected based on conditions. It does not replace domain matching in [Rule]. If the connection keeps changing during a test, check the On Demand conditions first; repeatedly adding REJECT rules will not fix a connection that is not staying active.

Understand rule order: matching stops at the first rule

In standard rule-based routing, rules are checked from top to bottom. When a request matches a rule, its specified policy is applied, and no further rules are checked for a “better” match. That is why precise allow rules usually go before broad blocking rules, while FINAL handles requests that did not match anything earlier.

Request enters the tunnel Rules checked from the top First matching rule found Specified policy applied Result recorded
[Rule]
# Allow this exact domain directly first
DOMAIN,help.example.com,DIRECT
# Then reject example.com and its subdomains
DOMAIN-SUFFIX,example.com,REJECT
# Send all other requests directly in this snippet; syntax example only
FINAL,DIRECT

In this three-rule example, help.example.com matches the first rule and uses DIRECT; media.example.com matches the second and uses REJECT. FINAL handles any other unmatched domains. If you move the second rule above the first, the help page will also be rejected because it is a subdomain of example.com.

Choose the matching scope: DOMAIN vs. DOMAIN-SUFFIX

Use DOMAIN when you want to block one specific hostname. Use DOMAIN-SUFFIX when you need to cover a base domain and all its subdomains. For both rule types, enter the domain itself—without a scheme, port, path, or query string. For example, https://ads.example.com/banner is not a valid domain field.

Rule exampleMatching scopeCheck before use
DOMAIN,ads.example.com,REJECTMatches ads.example.com exactlyConfirm the hostname exactly matches the one in the request log
DOMAIN-SUFFIX,example.com,REJECTMatches example.com and its subdomainsCheck whether login, images, and APIs share this domain suffix
IP-CIDR,192.0.2.7/32,REJECT,no-resolveMatches a single IPv4 addressThis is a documentation example address, not an actual blocking target

IP-CIDR matches an IP address range, while GEOIP matches based on an IP address’s geographic location. Neither is equivalent to matching a domain suffix. In the example, no-resolve means this IP rule will not trigger an additional domain lookup; if a request only has a domain at that point, do not assume it will match the address rule. Using REJECT against a shared IP may also affect other sites hosted at that address.

3 rules
Example from the previous section: exact exception, suffix block, and FINAL fallback
/32
Matches one IPv4 address, not an entire subnet
443
Common HTTPS port; do not include it in the DOMAIN field

Start with an exact match, then widen the scope

Start with a DOMAIN rule for a single hostname confirmed in the request log. Switch to DOMAIN-SUFFIX only after confirming that other subdomains should also be rejected. This avoids blocking an entire service domain unnecessarily.

Know the limits: REJECT cannot filter webpage elements

REJECT is suited to blocking independently identifiable network targets, such as a domain requested separately by a page. It is not a webpage element filter: if page content, images, and the content you want to block all use the same hostname, a simple domain rule cannot distinguish one path from another. Rejecting that domain may also break content APIs, login verification, or static resources.

HTTPS encryption does not mean all domain rules stop working, but REJECT itself does not decrypt and inspect webpage content. Do not enable HTTPS decryption or install a certificate just to block a network target; neither is needed to verify the rules in this guide. Also, a blank area on a webpage does not mean the rule failed: after a request is rejected, the page layout may not automatically remove the space it occupied.

Verify and roll back: trace false positives to actual requests

After saving changes in Config, confirm that the configuration is still active. Return to Home and check that Global Routing is set to Config. Reconnect if needed, then reopen the target page to trigger new requests. In the app’s request logs, check the destination domain or IP, the applied policy, and any visible rule details. Log locations and fields may vary; use what is shown in the current interface.

  1. Keep the original configuration: Save a recoverable copy before editing and note where you add each rule, so you can undo changes instead of piling on more rules.
  2. Change one thing at a time: Add one exact rule, save, and verify it. Avoid changing Global Routing, DNS, and multiple IP rules at once, or it will be difficult to identify what caused the change.
  3. Check for new requests: If the target request does not appear in the log, reload the page or reopen the relevant feature. This helps avoid mistaking cached content or an old connection for a new rule result.
  4. Check the applied policy: If the log shows DIRECT or another policy, check whether an earlier rule matched. If it shows REJECT but content is still visible, check the cache and other request domains.
  5. Roll back as narrowly as possible: Start by removing the most recently added rule. If the suffix block must remain, put the exact exception above it and use the allow policy required by your existing configuration.

Allowing a request does not necessarily mean using DIRECT. DIRECT means a direct connection; if a service should use a proxy in your existing setup, restore the policy it originally used. DIRECT above only illustrates exception ordering and should not be applied mechanically to every service. If the policy you need to restore refers to a policy group, make sure that group exists in the active configuration.

Why can I still open a site after adding a REJECT rule?

First check on Home that Global Routing is set to Config, then confirm the active file in Config. Trigger the request again and check the actual hostname. If an earlier allow rule matched, adjust the rule order instead of adding the same REJECT rule again.

The login button keeps spinning after I add a rule. What should I do?

Remove the rule you added most recently, reopen the login flow, and check the verification or API domains in the request log. If an overly broad DOMAIN-SUFFIX rule is blocking the request, narrow it to an exact DOMAIN match or add a necessary exact exception above it.

Does a successful Connectivity Test prove that blocking worked?

No. Connectivity Test on Home checks whether a connection is reachable; it does not confirm that a specific domain matched REJECT. Trigger a request from the feature you want to test, then check the handling record for that request.

Will manually added rules remain after updating a subscription?

First distinguish between updating a server subscription on Home and updating a configuration file in Config. Updating the server list is not the same as editing [Rule]; re-fetching a remote configuration may replace local changes. Save a copy before updating, then check the active file and rule positions afterward. Get subscription links from your service provider.

A successful final check requires both of the following: new requests to the target use REJECT as expected, and the login, images, and APIs you need to keep working still use the correct policies. Confirming that “a page will not open” is not enough to prove a rule is accurate. Reproducible targets, clearly defined matching scope, and a recoverable configuration are the basis for reliable maintenance.

Verify the App Store listing