Shadowrocket REJECT Rules Explained: What Domain Blocking Can and Can’t Do

REJECT blocks matching requests before an outbound connection is made. Learn how domain and IP rules work, how rule order affects them, and what rule-based blocking can’t cover.

At a glance

Shadowrocket’s REJECT policy blocks connections; it doesn’t filter page content. This guide is for users with a working connection who are ready to edit rules. Set Global Routing to Config, add a narrowly scoped domain or IP rule, check the request log to confirm a match, and then account for rule gaps, cached content, and content served from the same domain.

REJECT blocks connections, not individual page elements

When an app accesses the network, Shadowrocket checks connections routed through its processing path against your rules. If a rule matches REJECT, Shadowrocket won’t establish a normal outbound connection to the destination using DIRECT or PROXY. “Before a connection is established” refers to the outbound connection to the destination; it doesn’t mean the app hasn’t sent a request, or that no DNS lookup has occurred before the rule is evaluated.

App request Tunnel receives request Rules checked Request rejected App reports an error

What happens next depends on how the app handles errors: an image may fail to load, a separate analytics request may end, or the app may retry or show a timeout message. REJECT doesn’t generate a normal page for the app or automatically collapse blank areas in a webpage. A request can be rejected while the page appears unchanged.

These policies are separate from the proxy protocol in use. Shadowsocks, VMess, VLESS, Trojan, Hysteria2, and WireGuard describe proxy transports or tunneling methods. Switching protocols doesn’t give REJECT the ability to identify content inside an HTTPS page.

What domain and IP rules can match

When the destination domain is available at the matching stage, you can use DOMAIN or DOMAIN-SUFFIX. DOMAIN matches an exact hostname; DOMAIN-SUFFIX matches a domain and its subdomains. If you want to block just one endpoint, start with its exact hostname rather than applying a rule to the entire parent domain.

Domain match scope

DOMAIN
metrics.example.com,REJECT
DOMAIN-SUFFIX
example.com,REJECT
Matches against
The destination hostname, not the URL path

example.com and its subdomains are used only to illustrate the syntax; this isn’t a ready-to-use blocklist.

IP match scope

IP-CIDR
192.0.2.10/32,REJECT,no-resolve
GEOIP
CN,DIRECT
Matches against
The destination IP, an IP range, or an IP geolocation database

192.0.2.10 is a documentation example address. The GEOIP example shows a direct-allow policy, not a blocking recommendation.

/32 represents a single IPv4 address, not a broad range. no-resolve prevents an extra DNS lookup just for this IP rule; it doesn’t mean that DNS is disabled for all requests. If an app connects directly to an IP and there’s no usable domain information associated with it, a domain-only rule may not match.

IP rules have limitations too. Multiple domains may share a CDN address, and the same domain may resolve to different addresses depending on region, network, or time. Blocking every IP returned by a lookup may miss new addresses later and affect other services sharing those IPs. GEOIP relies on an IP geolocation database; it doesn’t identify a website’s actual content or operator.

Check dependencies before widening the scope. Login, CAPTCHA, images, and page content may use different subdomains of the same parent domain. Changing a DOMAIN rule to DOMAIN-SUFFIX can block an entire set of required requests instead of just one endpoint.

Rules are checked in order; REJECT has no special priority

With Config routing, rules are checked from top to bottom, and the first matching rule determines the policy. REJECT doesn’t automatically override an earlier DIRECT or PROXY rule just because it blocks traffic. Put specific exceptions before broader rules, and keep FINAL at the end of the rules section to handle connections that haven’t matched earlier rules.

[Rule]
DOMAIN,login.example.com,DIRECT
DOMAIN,metrics.example.com,REJECT
DOMAIN-SUFFIX,example.com,PROXY
GEOIP,CN,DIRECT
FINAL,PROXY

In this example, which illustrates rule order only, login.example.com matches DIRECT first, metrics.example.com matches REJECT first, and other requests under example.com then match PROXY. Move DOMAIN-SUFFIX to the top, and it will match the first two hostnames before their specific rules can take effect.

ConfigurationResultHow to fix it
A broad allow rule comes before REJECTThe destination matches the allow rule firstMove the exact REJECT rule above the relevant broad rule
REJECT comes after FINALFINAL has already handled the requestKeep FINAL at the end of the rules section
Multiple policies target the same hostnameThe first matching rule takes effectCheck the full rule order, not just search for REJECT

Troubleshooting: Find the rule that actually matched before widening the block

If the request log shows DIRECT or PROXY, first fix the earlier rule or the current routing mode. Adding more similar REJECT rules won’t change a request that has already matched an earlier rule.

Confirm Config is active, then run a minimal test

Having a rule file in Config doesn’t guarantee that current requests are being handled by it. First check Global Routing on Home. Proxy and Direct are overall routing modes; to test rules, explicitly select Config. Scene is a context-based routing mode—seeing Scene selected doesn’t by itself confirm how rules in the current configuration are being applied.

  1. Keep a backup. In Config, confirm which configuration is active and save a restorable copy before editing. Don’t overwrite a complete rule set you haven’t reviewed.
  2. Add one precise rule. Use the hostname shown in the request log and follow the structure DOMAIN,hostname,REJECT. Here, “hostname” indicates the field; it isn’t a ready-to-paste rule.
  3. Confirm the active configuration. Save your changes and make sure the edited configuration is in use. On Home, set Global Routing to Config and confirm the connection is enabled.
  4. Trigger a new request. Leave the target page and open it again. If needed, quit and reopen the app. Don’t rely on an image that has already loaded or an old browser tab.
  5. Check the log. Find the destination hostname or IP in the request log and check which rule and policy matched. A new request showing REJECT confirms that this test reached the reject path.
  6. Test recovery. Temporarily remove the rule you just added, then trigger the same request again. Compare the connection and app behavior before and after removal to confirm the rule caused the change.

Settings → On Demand controls automatic connections based on conditions; it isn’t a REJECT toggle. If the tunnel disconnects during testing, later requests may no longer follow the same processing path. Check the connection status before concluding that a rule has failed. For persistent connections, don’t assume that editing a rule closes existing sessions; make a new connection to test it.

Record test conditions, not speed results. Note the destination hostname, Global Routing mode, matching policy, and whether you restarted the app. Without these details, seeing that “the page still loads” doesn’t tell you whether REJECT worked.

Limitations involving HTTPS, caches, and content on the same domain

Domain and IP rules match connection destinations. Suppose regular content is at https://example.com/article and another type of content is at https://example.com/promo. Both use the same hostname. DOMAIN and DOMAIN-SUFFIX can’t distinguish between those paths; blocking the hostname could also block the article.

443
The default port commonly used by HTTPS; it doesn’t identify content type
53
The port commonly used by traditional DNS; it doesn’t cover every DNS transport
4 items
Global Routing:Proxy / Direct / Config / Scene

A port can hint at the type of traffic, but it can’t precisely identify content. Regular webpages and other HTTPS requests may both use port 443, so blocking the entire port isn’t a selective filter. Even when the destination domain is available, that doesn’t mean the URL path, request body, or response content inside an encrypted connection can be read. REJECT doesn’t decrypt traffic.

URL Rewrite is a separate request-rewriting mechanism; its capabilities shouldn’t be attributed to REJECT. If a connection rule can’t isolate specific content, preserve necessary functionality and narrow the target rather than expanding IP ranges in an attempt to remove page elements.

Common issues and recovery steps

Why is the page still showing after I added REJECT?

First, confirm that Global Routing is set to Config on Home. Then trigger a new request and check the log. If the new request shows REJECT but an old image remains, check the app’s cache. If there’s no new log entry, you can’t use the page already on screen to tell whether the rule worked.

Why did blocking also stop me from logging in?

Remove the DOMAIN-SUFFIX or IP-CIDR rule you added most recently, then reopen the app and test login again. If it works, check whether the login service and the target content share a domain or IP address. If they can be distinguished, use an exact DOMAIN rule; otherwise, keep the connection required for login.

Why did my rule stop working after I updated the subscription?

In Config, check which file is active and whether your local changes are still present in the Rule section. Updating a server subscription and replacing a remote configuration are different operations. If an update replaced the entire configuration, your local rules may have been overwritten. Restore them from your backup and check their order again.

Can I copy in a large list of IPs to block?

Don’t add a large batch at once. Start with one actual destination and check whether it shares a CDN address or may resolve to other addresses later; then decide whether to use IP-CIDR. Change one related group of rules at a time and keep a restorable backup so you can identify which rule caused a problem.

This guide assumes you already have your own service provider and subscription; get subscription details from your provider. Connection details from your provider solve the connection setup, while REJECT handles matching and blocking in your current configuration. They serve different purposes. After testing, keep rules precise, understandable, and easy to roll back instead of accumulating entries whose purpose is unclear.

Get Shadowrocket and follow the setup guide

The iPhone and iPad version costs $2.99 as a one-time purchase on the App Store. The Mac (Apple Silicon and Intel), Windows, Android, and Linux versions are free. For iPhone and iPad, check the App Store listing for system requirements. Buying the app is not the same as buying a service plan; you’ll still need your own connection configuration.

Download Shadowrocket for all platforms