How to Write Shadowrocket REJECT Rules: Blocking Requests, Syntax, and Limitations

Learn how REJECT blocks requests during rule matching, see DOMAIN-SUFFIX and IP-CIDR examples, and troubleshoot rule limitations and unintended blocks.

At a glance

In Shadowrocket, REJECT is a request-routing policy, not a webpage element filter. This guide is for users with a working configuration who maintain their own rules. First, set Global Routing to Config. Then block the target with the narrowest practical rule and check the match in the connection log. If something is blocked by mistake, undo only the change you just made. The domains and addresses in these examples illustrate syntax; they are not a blocklist.

1. What REJECT Does During Rule Matching

In short, when a request enters Shadowrocket’s rule-processing flow and matches a rule whose policy is REJECT, the request is denied instead of continuing to the destination through a proxy or direct connection. The requesting app may show a failed resource, a connection error, or repeated retries. The exact message depends on the app making the request. A blank page alone does not prove that REJECT matched.

Request enters the tunnel Destination details are identified Rules are checked in order A reject policy matches Connection fails

Rules are generally checked in the order listed in the configuration. Once an applicable rule determines the policy, later rules do not change the result for that request. So adding a rule does not necessarily mean a request will use it. Earlier broad allow rules, the configuration file actually in use, and the current routing mode can all affect the outcome.

For example, a page’s text, images, and analytics requests may share a destination under the same domain. A domain rule alone cannot distinguish their purposes. Setting REJECT for the whole domain could also block resources the page needs.

2. Check Config and Global Routing First

Save a copy of your current configuration before making changes. In Config, check which file is selected, open its editing view, and inspect the rules section. The exact editing controls depend on what the app currently displays. Don’t edit a file that isn’t active and then judge the rule by what happens in a webpage.

SettingMeaning and defaultRecommended test setup
Home → Global Routing → ConfigRoutes traffic according to the current configuration; the selected default may vary by app version.Use Config to test the REJECT rules in your configuration.
Global Routing → ProxyGlobal proxy mode; not the baseline for testing the rules in this guide.Switch back to Config before testing; don’t use this mode to determine whether a rule matched.
Global Routing → DirectGlobal direct mode; not the baseline for testing the rules in this guide.Switch back to Config before testing.
Global Routing → SceneRoutes traffic according to the selected scene; the result depends on that scene’s settings.Note the current state first. Use Config for the test, then restore the previous setting if needed.
Settings → On DemandOn-demand connection settings; the default switch and conditions depend on what the app currently displays.During testing, make sure the connection stays active so automatic connection conditions don’t interfere with reproducing the issue.
  1. Note the selected configuration, Global Routing state, and how the target app behaves normally.
  2. In Config, keep a copy, then edit the rules section of the file that’s actually in use.
  3. Return to Home, confirm the connection is on, and set Global Routing to Config.
  4. Save and confirm the change has loaded, then make the target app send a new request.

Connection entries on Home and rule files in Config are separate settings. Updating a connection subscription doesn’t mean your edited rules have loaded. If the configuration updates remotely, also check that your local changes are still there after the update.

3. Correct DOMAIN-SUFFIX and IP-CIDR Syntax

Text rules use English commas to separate fields, not Chinese commas. Here are four standalone syntax examples, not a complete configuration to replace yours with. The domains use reserved example domains, and 192.0.2.0/24 is a documentation-only address range; none of these values refer to real targets that should be blocked.

DOMAIN,metrics.example.com,REJECT
DOMAIN-SUFFIX,example.com,REJECT
IP-CIDR,192.0.2.18/32,REJECT,no-resolve
IP-CIDR,192.0.2.0/24,REJECT,no-resolve

Domain rule fields

Rule type
DOMAIN or DOMAIN-SUFFIX
Match value
metrics.example.com or example.com
Policy
REJECT — deny matching requests
Defaults and recommendations
There’s no universal default match value. Start by testing with DOMAIN.

Enter only the hostname in the domain field—not https://, a path, or a port.

Address rule fields

Rule type
IP-CIDR — matches an IPv4 address range
Match value
192.0.2.18/32 — a single address
Policy
REJECT — deny matching requests
Optional parameter
no-resolve — avoids actively resolving a domain to match this IP rule
Defaults and recommendations
There’s no universal default address range. Check a single address first, then consider a range.

no-resolve does not disable DNS globally or mean “reject all DNS lookups.”

DOMAIN-SUFFIX,example.com,REJECT matches example.com and subdomains such as img.example.com. It does not match every domain that happens to contain that string. If you only want to block metrics.example.com, start with DOMAIN rather than expanding the rule to the entire parent domain.

/32
Single IPv4 address match range
/24
Match range containing 256 IPv4 addresses
3 fields
Basic domain rule: type, match value, policy

Bottom line: start with one domain or one address

If DOMAIN or /32 can target the destination, don’t broaden the rule to a domain suffix or an entire address range. Expand the match only when connection logs show that the wider scope is necessary.

4. Rule Order, Exceptions, and the FINAL Fallback

If you need to allow a subdomain, put the exception before the broader reject rule. This example shows ordering only: send account.example.com direct, reject other example.com requests, then send unmatched requests direct. DIRECT is an explicit choice for this example, not a recommendation that everyone should use direct routing as the fallback.

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

In your actual configuration, keep the policies it requires. If the exception needs to use a proxy, don’t copy DIRECT mechanically; use the appropriate policy already present in your configuration. Don’t append a second [Rule] section to the end of the file. Edit the existing rules section and confirm the final order.

GEOIP matches based on the region associated with an address; it doesn’t classify whether a particular website should be blocked. Changing a broad GEOIP policy to handle one domain can cause unnecessary side effects. Prefer moving or narrowing rules directly related to the target.

5. What Rule-Based Blocking Can’t Handle

REJECT makes decisions about connection destinations; it doesn’t parse page layouts. A webpage path, query parameter, or page content in an HTTPS request can’t be used directly as a DOMAIN-SUFFIX match value. For mixed content on one domain, cached content, or shared infrastructure, understand the limits before deciding to reject the destination.

ScenarioWhat you may seeWhat to do
Different content hosted on the same domainBlocking one target also affects page content, sign-in, or images.Check for a dedicated subdomain. If the requests can’t be distinguished, keep the functionality you need.
Multiple sites share one addressAn IP-CIDR reject rule also prevents other domains from connecting.Prefer a domain rule; avoid blocking a shared address range directly.
Page content is cachedYou can still see old content after the rule matches.Make a new request and verify it in the connection log; don’t rely on a page that was already open.
The target uses both IPv4 and IPv6With only an IPv4 rule, connections to other addresses may still succeed.Check the actual destination address. IP-CIDR doesn’t cover IPv6; check the relevant syntax separately.
The app retries automatically or switches domainsAfter one destination is rejected, requests to another destination may appear.Check the purpose of each request. Don’t broaden the rule to an entire address range just because the app retries.

If a connection is already established, subsequent page behavior may not reflect the new rule right away. Test rules against new connections created after the change. Close and reopen the target page; if needed, quit and relaunch the app. Also account for connection reuse so you don’t mistake traffic on an existing connection for a failure of the new rule.

6. Troubleshoot with Connection Logs

Change only one thing at a time. Reproduce the failed request, then check the app’s connection records and Log. The available views and fields depend on what the app currently displays. Note the destination domain or IP, request time, final policy, and any visible matching rule. Before sharing logs, hide subscription URLs, tokens, and other account information.

  1. Confirm the request is being processed: Check the connection status on Home and Global Routing. If no new request appears in the log, first check the connection, cache, and whether the target actually made a request.
  2. Check the destination: The site name shown on a page may not match the domain of the resource that failed. Use the connection record from the relevant time to check the actual hostname and address.
  3. Check the active file: Return to Config and confirm you edited the current configuration. Make sure the rule is still there after saving and loading the file.
  4. Check the order: Review rules from top to bottom for an earlier matching allow rule, and check where FINAL appears.
  5. Undo the change: Remove only the REJECT rule you just added, then repeat the same action. If the feature works again, the new rule is worth investigating—but use the logs to determine exactly what it depends on.
  6. Narrow the match and test again: Replace a suffix rule with an exact domain, or an address range with a single address. Test the affected features individually, such as sign-in, images, search, and playback.

Why can the target still open after I save the rule?

On Home → Global Routing, select Config, then check which file is active in Config. Make a new request and confirm the destination matches the rule and that the rule comes before FINAL. A page already in the cache doesn’t prove the rule matched.

Sign-in stopped working after I added DOMAIN-SUFFIX. What should I change?

First remove the new rule and test sign-in again. Then use the connection records from the failed attempt to identify the domains required. Narrow the reject rule to the actual destination. If you need an exception, put it before the reject rule and keep the routing policy that domain needs.

Does adding no-resolve prevent DNS requests?

No. It limits active lookups made to match that IP rule; it doesn’t disable other DNS behavior. To reject a domain, use DOMAIN or DOMAIN-SUFFIX rather than using this parameter as a substitute for a domain rule.

Blocking stopped working after a configuration update. Should I import the subscription again?

First check whether your local rule changes are still in the active rules section in Config. A remote configuration update may replace the file contents. Keep a copy, compare the file before and after the update, and restore only the rules you still need. Reimporting a connection subscription doesn’t replace this step.

After testing, keep only the smallest necessary change and a note explaining its purpose. Don’t leave temporary global modes, broad address blocks, or wide suffix rules in your long-term configuration. When the same issue comes up again, it’s easier to troubleshoot if you can identify and undo one specific rule than if you’re maintaining a long list with no clear source.

Download on the App StoreVerify the official listing first