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.
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.
DIRECT: Connects directly to the destination; the request is still allowed to access the network.PROXY: Routes traffic through the selected proxy policy; it doesn’t block the request.REJECT: Blocks matching requests; it doesn’t replace content or reformat a page.
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.
| Configuration | Result | How to fix it |
|---|---|---|
| A broad allow rule comes before REJECT | The destination matches the allow rule first | Move the exact REJECT rule above the relevant broad rule |
| REJECT comes after FINAL | FINAL has already handled the request | Keep FINAL at the end of the rules section |
| Multiple policies target the same hostname | The first matching rule takes effect | Check 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.
- 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.
- 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. - 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.
- 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.
- 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.
- 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.
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.
- Content is cached: The app may display data from disk or memory without making a new network request for REJECT to block. It may continue using cached content when you revisit the page.
- Content is part of the main response: Regular page content and other content may arrive in the same request. A connection-level rule can’t keep one part while blocking another.
- The page structure remains: Even if a remote image request fails, the webpage may still show the reserved space, heading, or button.
- The app switches endpoints: After a failed request, the app may contact another domain. The original rule applies only to the destination it matched; it won’t infer what a new endpoint is used for.
- The request bypasses the processing path: If the connection is off or traffic is excluded, adding rules won’t help. First confirm that the traffic passes through the active configuration.
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.