How Shadowrocket REJECT Rules Work: What Rules Can Block and What They Can’t

Learn how REJECT rules block connections during request matching, how to use DOMAIN-SUFFIX and URL-REGEX, and why rules can’t fully block same-domain content or in-app requests.

At a Glance

In Shadowrocket, REJECT blocks connections; it doesn’t remove elements from a page. First, select a configuration containing the rules you need in Config, then go to Home → Global Routing and choose Config. This guide is for users who already have their own provider details and subscription and want to adjust local rules. It covers domain matching, URL visibility, rule order, and caching, with small-scale tests to help avoid blocking the wrong traffic.

1. Where REJECT Takes Effect: Matching Requests, Not Changing Pages

After an app makes a network request, only traffic handled by Shadowrocket can be evaluated against the active configuration’s rules. Rules match information such as the available domain, destination IP, or URL. When a request matches a rule with the REJECT policy, the connection is blocked instead of being sent to a DIRECT or proxy policy. The app may show a loading error or retry message, or switch to another address on its own.

App request Traffic handling Identify conditions Match rules Block connection

This process doesn’t understand page layout or determine whether an image or text is an ad. If the content loads from a separate domain, blocking connections to that domain may prevent it from appearing. If the content is already part of the main page response, REJECT can’t remove just that portion. Empty placeholders, loading indicators, and messages displayed by the app itself also aren’t things connection rules can directly clean up.

First check whether the content you want to block has its own network request, then choose a matching condition. A placeholder remaining on the page doesn’t mean the request wasn’t blocked; content not appearing temporarily doesn’t prove that a rule matched.

2. Using DOMAIN-SUFFIX: Start with a Specific Domain

DOMAIN-SUFFIX matches a domain and its subdomains. ads.example.com below is only a syntax example, not a ready-to-use blocklist. It matches ads.example.com and img.ads.example.com, but not notads.example.com. Don’t set an entire parent domain to REJECT just to match one subdomain.

[Rule]
DOMAIN-SUFFIX,ads.example.com,REJECT
FINAL,DIRECT

This example illustrates the logic of rejecting a target domain while allowing other connections directly. It isn’t a complete configuration for every network setup. If the existing configuration’s FINAL points to another policy, preserve that fallback behavior instead of mechanically changing it to DIRECT. If your existing configuration contains [Rule], add the rule to that section rather than creating a duplicate section with the same name.

  1. Back up the current configuration in Config, and make sure you’re editing the file you intend to enable.
  2. Place the target domain’s REJECT rule before broad allow rules that might match first, and keep FINAL at the end of the rules.
  3. Save and select the configuration, then go to Home → Global Routing and choose Config.
  4. Make sure the connection is on, then trigger the target request again. Check that normal functions such as sign-in, images, and page content still work.

With the usual first-match rule order, the first matching rule determines the policy. For example, if DOMAIN-SUFFIX,example.com,DIRECT comes before a REJECT rule for ads.example.com, the latter may never get a chance to apply. Put specific conditions first and broader ones later. FINAL handles requests that don’t match any preceding rule.

3. Global Routing and Match Conditions: Connection Triggers Aren’t Blocking Rules

When troubleshooting rules that don’t seem to work, first check Home → Global Routing. Proxy, Direct, Config, and Scene are different routing modes; an active connection alone doesn’t mean the configuration’s rules are in use. For the baseline test in this guide, choose Config so the selected configuration’s rules can route traffic. Check Scene settings separately; they aren’t required for this basic test.

Basic Domain Test

Configuration
Config → Select the test configuration
Routing
Home → Global Routing → Config
Target rule
DOMAIN-SUFFIX,ads.example.com,REJECT
Fallback example
FINAL,DIRECT

The example is for syntax only. Use a verified, real target domain for testing.

Connection and Matching Limits

Automatic connection
Settings → On Demand
What On Demand Does
Starts a connection when conditions are met; it doesn’t replace REJECT rules
IP-CIDR condition
Matches the destination IP against a network range
GEOIP condition
Matches based on the geographic data for the destination IP

Check the connection and Config first, then verify what matching information the request actually provides.

Domain rules need access to the domain associated with a request. If an app connects directly to an IP, uses a different resolution path, or exposes limited request details, don’t assume a domain condition will match. IP-CIDR can match a network range, and GEOIP can match geographic data, but neither can tell what a particular IP is used for. Shared servers and content delivery addresses are especially prone to causing unintended blocks.

Shadowsocks, VMess, VLESS, Trojan, Hysteria2, and WireGuard are connection protocols, not conditions for identifying page content. If a request matches REJECT, changing the protocol won’t allow that blocked request through. Check the matching rule and policy first, then investigate whether there’s a separate connection issue.

4. Using URL-REGEX: Path Matching Depends on URL Visibility

URL-REGEX uses a regular expression to match URLs, allowing you to specify paths more precisely than with domain rules. The example below matches paths beginning with /banner/ on the example host. ^ anchors the match to the start of the URL, \. represents a literal period, and https? matches HTTP or HTTPS. A regular expression can describe a condition, but that doesn’t mean the client can see the full URL for every connection.

URL-REGEX,^https?://ads\.example\.com/banner/,REJECT
Condition Information required Main limitation
DOMAIN-SUFFIX Destination domain Can’t distinguish different paths on the same domain.
URL-REGEX URL available for matching Encrypted HTTPS paths generally can’t be read directly.
IP-CIDR Destination IP and network range May affect multiple services sharing the same IP.

HTTPS encrypts HTTP request data, including paths and query parameters. Even when a connection uses the standard port 443, knowing the hostname doesn’t mean you can read /banner/. Matching HTTPS paths usually requires the relevant traffic to be processed by MITM, along with the target host being in scope, a trusted certificate, and app compatibility. Don’t treat a URL-REGEX rule as if it can read encrypted paths without any additional setup.

Some apps use certificate pinning or other verification and may reject connections processed by MITM. If that happens, stop processing traffic for that scope and restore the original settings; don’t assume the app error means the regular expression is wrong. Plain-text HTTP can expose URL information through supported processing paths, but verify matches against actual requests and logs.

Bottom Line: Use Domain Rules for Separate Domains

Once you’ve confirmed that the target loads from a separate domain, test a DOMAIN-SUFFIX rule first. Consider URL-REGEX only if you need to distinguish paths on the same domain and can verify that the URL is visible.

5. What REJECT Can and Can’t Block: Same-Domain Content, Caches, and In-App Requests

REJECT works best for identifiable, separate connections that can be blocked without breaking essential features. In-app requests don’t automatically bypass rules: if they’re within Shadowrocket’s handling scope and meet a match condition, they can be blocked too. The challenge is that these requests may share the main service domain, use changing addresses, reuse an existing connection, or never make a new network request at all.

For example, if the sign-in API and the resource you want to block both use api.example.com, applying REJECT to that domain may also prevent sign-in. If multiple domains share an IP, blocking its network range may not be any more precise. Choose rule granularity based on the request structure; don’t compensate for insufficient evidence by blocking a broader range.

6. Test and Roll Back: Change One Thing at a Time

A useful test checks both whether the target request was blocked and whether essential features still work. Connectivity Test diagnoses reachability for the selected connection; it doesn’t test whether REJECT matched. A normal test result doesn’t prove a blocking rule worked, and an abnormal result doesn’t prove that the target domain was blocked.

  1. Record a baseline: Keep the original configuration and note where the target content appears, the confirmed request domain, and whether normal functions such as sign-in work.
  2. Make one change: Add just one specific domain rule. Don’t change the protocol, fallback policy, and DNS settings at the same time.
  3. Check the status: Confirm which file is selected in Config, that Home → Global Routing → Config is selected, and that the connection is on.
  4. Make a fresh request: Reload the target page or reopen the app to rule out interference from existing connections and cached content.
  5. Check the evidence: Use available request records or logs to check the target domain, matched rule, and final policy; don’t judge by the page’s appearance alone.
  6. Compare and roll back: Remove the rule or restore the backup, then repeat the same steps. If an essential feature is affected, restore a working state first.

Why is the content still there after adding REJECT?

Go to Home → Global Routing and confirm Config is selected, then check which file is selected in Config. Trigger the request again. If there’s no new record for the target request, consider cached content, bundled assets, or an existing connection before adding broader rules.

Sign-in stopped working after blocking. How do I restore it?

In Config, remove the REJECT rule you just added or restore a backup, then save and select the configuration again. Check whether the target domain is shared with the sign-in API. Don’t block the entire parent domain or a shared IP range without verifying the impact.

Why doesn’t URL-REGEX match an HTTPS path even though the pattern is correct?

First confirm that the actual request URL matches the expression, then verify that the full URL is visible for that traffic. If only the domain is available, there isn’t enough information for a path rule. Don’t infer that MITM is active just because the connection uses port 443 or succeeds.

Why did my custom rule disappear after updating the configuration?

Distinguish a server subscription update from a remote configuration update. The former mainly updates server details; the latter may replace configuration contents. Keep a separate backup before editing. After an update, check the rules, their order, and the selected configuration in Config—not just the server list on Home.

For more on routing conditions, see the Technical Reference. For initial connection setup and routing modes, see the Global Routing section of the Getting Started guide. This site doesn’t provide, sell, or recommend servers or subscriptions. Buying the app and using a network service you already have are separate matters.

Verify the Official App on the App Store