REJECT is a request-handling policy, not a webpage element filter. This guide is for users who already use their own configuration, provider, and subscription in Shadowrocket and want to add blocking rules or troubleshoot unintended effects. First, set Global Routing to Config, then check the matched rule, its target scope, and the fallback policy. By the end, you’ll be able to distinguish between a rule that didn’t match, a request that was rejected after matching, and page content that rules can’t target.
Where REJECT applies
Shadowrocket uses rules in your configuration to determine how traffic is handled. REJECT rejects requests that match a rule. Like DIRECT and PROXY, it’s a policy you can specify at the end of a rule, but the outcome differs. Rules select the target; the policy determines what happens to it. Don’t confuse the two.
This flow describes only requests handled by Shadowrocket that ultimately match REJECT. Turning on the app doesn’t guarantee that traffic is currently routed according to your configuration rules. Check Global Routing on Home first. To test a rejection rule in your current configuration, use Config and confirm that the configuration you edited is selected there.
- Global Routing → Config: Requests are handled according to the current configuration rules. This is required to test the rules in this guide.
- Global Routing → Proxy: Routes traffic through the global proxy policy. This doesn’t verify whether a REJECT rule in your configuration works.
- Global Routing → Direct: Routes traffic directly. This likewise doesn’t prove that a configuration rule matched.
- Settings → On Demand: Manages automatic connections based on conditions; it doesn’t define which domains should be REJECTed.
If you use a Scene under Global Routing, check its current settings rather than inferring the rule path from the connection toggle alone. For troubleshooting, keep the test conditions fixed on Config to reduce interference from automatic switching and different routing modes.
How rules select requests
A basic rule consists of a match type, a match value, and a policy. For example, DOMAIN-SUFFIX,example.com,REJECT: the match type is DOMAIN-SUFFIX, the target is the example.com domain suffix, and the policy is REJECT. Here, example.com is a reserved example domain, not a real service you should block.
[Rule]
DOMAIN,login.example.com,DIRECT
DOMAIN-SUFFIX,example.com,REJECT
FINAL,PROXY
This example illustrates rule order; don’t replace your existing configuration with it wholesale. Configuration rules are evaluated in order. A request identified as login.example.com is handled by the earlier exact-match rule; other domains matching the example.com suffix are rejected. Requests not handled by earlier rules fall through to FINAL. DIRECT is shown only to illustrate an exception; in a real setup, keep the policy that already works for that service.
Domain matching scope
- DOMAIN
DOMAIN,ads.example.com,REJECTmatches only this exact domain.- DOMAIN-SUFFIX
DOMAIN-SUFFIX,example.com,REJECTmatches the root domain and its subdomains.- A non-matching domain
notexample.comis not a subdomain of example.com.
When targeting a single host, start with DOMAIN to avoid blocking a wider range.
Address and fallback rules
- IP-CIDR
IP-CIDR,192.0.2.0/24,REJECTmatches the specified IPv4 subnet.- GEOIP
GEOIP,CN,DIRECTmatches based on an IP geolocation database.- FINAL
FINAL,PROXYhandles requests that haven’t matched an earlier rule.
192.0.2.0/24 is a documentation example subnet. Address rules aren’t interchangeable with domain rules.
Domain rules require domain information that can be matched, while address rules use the destination IP address. DNS resolution, DNS caches, and whether an app connects directly by IP can all affect the information you see. Don’t assume that every related connection reaches rule matching with the same domain just because it appears in the browser’s address bar.
What can be blocked
REJECT applies to requests, not individual areas of a screen. A page may request its main document, images, fonts, analytics, and login endpoints separately. If one of these uses a distinct domain that matches a rule, requests to that target can be rejected. Whether the rest of the page still works depends on whether it relies on that target.
| Example scenario | What REJECT can and can’t do | What to check |
|---|---|---|
| Additional resources use a separate domain | Requests to that domain can be rejected, but the page won’t necessarily remove the resulting blank space. | Check the actual resource domain, not just the page name. |
| Main content and additional content share a domain | DOMAIN-SUFFIX can’t distinguish between them by URL path. | Rejecting the entire domain may also break the main content, images, or interactive features. |
| Content is already cached locally | Adding a rejection rule won’t clear content an app has already saved. | Check whether a new request was actually made so you don’t mistake cached content for a rule that failed. |
| Content is embedded directly in the main response | A domain rejection can’t remove just one piece of text or one layout element from a response. | Distinguish separate network requests from content in the same response. |
| The target uses an IP address directly | Don’t assume DOMAIN-SUFFIX will always have a domain to match. | Check the actual destination address and matched rule in the connection record. |
HTTPS commonly uses TCP 443, and HTTP/3 commonly uses UDP 443, but a port number doesn’t reveal what a request is for. Normal API calls and other resources on the same domain may both use port 443. DOMAIN-SUFFIX has no port filter, and a different port doesn’t make it a way to identify a different type of service.
Takeaway: Identify a distinct target before adding a rejection rule
Add the narrowest possible DOMAIN rule only after confirming that the target can be separated from normal features. If they share a domain, don’t reject the entire suffix based only on a URL path.
Why rules can block more than intended
Unintended blocking is usually caused not by a syntax error but by a match scope broader than expected. Add DOMAIN-SUFFIX,example.com,REJECT to a configuration, and login.example.com, static.example.com, and api.example.com are all in scope. A login page that loads but can’t submit, or text that appears without its images, may mean different subdomains handle different functions.
- Root domain scope is too broad: You meant to reject ads.example.com but entered example.com, affecting accounts, images, and APIs as well.
- A shared address is blocked wholesale: Multiple domains may use the same hosting or delivery address. Expanding an observed IP address into an IP-CIDR subnet may block unrelated services.
- A required service is mistaken for an extra resource: CAPTCHAs, account verification, payment redirects, and media authorization may depend on another domain. The page may still appear, while essential actions no longer work.
- An exception rule is in the wrong order: If a precise allow rule comes after a broad rejection rule, the earlier match has already determined the outcome; the later exception can’t undo it.
- You edited a different configuration than the one in use: You changed one file in Config, but another configuration is selected, sending troubleshooting in the wrong direction.
If something works only occasionally, don’t assume REJECT is failing at random. The app may reuse an existing connection, load cached content, or switch to another service domain. Repeat the same action to make a fresh request, then use the connection record to confirm the target. Don’t compare results from different pages or account states as if they were equivalent.
Troubleshoot by changing one variable at a time
Before testing a rejection rule, keep a restorable copy of your configuration and change only one target. Don’t switch policies, adjust DNS, update a subscription, and add multiple rules at the same time; even if things start working, you won’t know which change made the difference. The steps below require no changes to your existing provider—just check local rules against actual requests.
- Record the baseline: Note the failing action, such as “open the login page and submit the form,” and when it happened. Check whether it worked before the change.
- Keep the routing mode fixed: On Home → Global Routing, select Config. Then confirm the current configuration in Config. If the connection changes automatically during testing, also check the conditions under Settings → On Demand.
- Reproduce the issue once: Repeat the same action and look in the app’s available connection records or logs for the destination domain, IP, matched rule, and policy at that time. Record only the fields shown; don’t guess at missing information.
- Narrow the rule: If a broad DOMAIN-SUFFIX rule matched, remove that rule in a test copy first, then consider replacing it with DOMAIN based on the actual target. Leave other rules and the original fallback policy unchanged.
- Apply the change and test again: Save the configuration and confirm that the change has been applied. If needed, reconnect when it’s safe to interrupt network tasks, then repeat the same action to avoid reusing an existing connection.
- Compare with a rollback: If removing the rule restores the feature and adding it back causes the failure again, you have stronger evidence that the rule is responsible. Without this comparison, keep checking other rules and targets instead of continually widening the allow scope.
A connection failure in the logs doesn’t prove that REJECT matched. DNS resolution failures, connection timeouts, and errors returned by the remote server can all make something appear “unavailable.” Look for the policy and rule fields first. If the record doesn’t provide enough information, treat the cause as unconfirmed. Before sharing troubleshooting details, redact credentials in subscription URLs, account information, and unnecessary browsing records.
Takeaway: Restore the feature before tightening rules
First remove the individual rejection rule confirmed to cause the problem and restore the previously working policy. Then test more precise targets one at a time. Don’t permanently allow an entire parent domain to mask an issue you haven’t identified.
Frequently asked questions
Why is the content still on the page after I add a rule?
First, check Home → Global Routing and select Config, then confirm the current file in Config. Next, reload the page and check the actual target. If the content comes from a cache, the main response, or another domain, the new DOMAIN-SUFFIX rule may not cover it. REJECT also won’t remove a placeholder left on the page.
Why can’t I log in after blocking something? What should I allow?
First, remove the rejection rule you added most recently in a test copy and repeat the login action. If that fixes it, use the records to identify the full domain required for login. Add a DOMAIN rule before the broad rejection rule and use the policy that already works for that service. Don’t switch every related parent domain to DIRECT.
Would changing the domain rule to IP-CIDR make blocking more precise?
Not necessarily. Addresses can change or be shared by multiple services. Use IP-CIDR only when you specifically need to handle a particular destination address or subnet. Don’t treat an address from a single DNS lookup as a permanent, exclusive identifier for a service. Test at the domain level first, then check whether an address rule would affect a wider range.
Do I need to rewrite REJECT rules after updating my subscription?
First, check what actually changed: a server entry or a configuration file. Updating a subscription doesn’t prove that local rules changed. If the current configuration was also updated remotely, compare rule contents, order, and which configuration is selected. Make adjustments only after confirming that a change was lost or the target has changed; don’t append the same rule after every update.
For routine maintenance, keep a record of three things: the exact target rejected, why the rule was added, and how to undo it. When a normal feature breaks, check recent changes first, then retest by changing one variable at a time. The number of rules isn’t a measure of effectiveness; clear scope, explainable matches, and easy rollback make rules easier to maintain over time.