At a glance

This guide is for users with a working connection who want to add domain-blocking rules in Config. First, distinguish match conditions from the REJECT policy; then add a precise rule, check connection logs, and assess whether shared-domain resources, cached content, or in-app content are beyond the scope of domain rules. The domains and addresses below are reserved examples used to explain syntax, not a ready-to-use blocklist.

1. REJECT is an action taken after a match—not a content filter

Shadowrocket rules answer two separate questions: what conditions a connection must meet, and what happens when it does. DOMAIN-SUFFIX, DOMAIN, and IP-CIDR are match conditions; REJECT is an action. Adding a domain to a rule does not identify ads, analytics code, or video segments on a webpage. It rejects connections that meet the rule's conditions.

App starts a connection Traffic enters the tunnel Rules are checked in order A reject rule matches The connection to the destination fails

This flow applies only to traffic that actually passes through Shadowrocket and is handled by the active rules. If traffic never enters the tunnel, rules cannot act on it. If traffic enters the tunnel but the overall routing mode is Proxy or Direct, that alone does not tell you whether a Config rule is working. To troubleshoot, check the connection status on Home first, then review Global Routing.

What happens after a connection is rejected depends on the app: it may show a failed resource, a blank placeholder, or repeatedly retry. REJECT does not remove page layout, guarantee faster loading, or replace remote content with something else.

2. DOMAIN and DOMAIN-SUFFIX: syntax and scope

For domain rules, enter only the hostname—not https://, a port, path, or query string. For a request to https://ads.example.com:443/banner?id=1, the hostname to check is ads.example.com. Port 443 is the connection port, and /banner is the path; neither belongs in a DOMAIN-SUFFIX domain parameter.

DOMAIN,ads.example.com,REJECT
DOMAIN-SUFFIX,metrics.example.com,REJECT

Exact hostname match

Rule type
DOMAIN
Parameter
ads.example.com
Policy
REJECT
Match scope
Only ads.example.com, not img.ads.example.com

For the first test, use an exact hostname to keep the impact limited.

Domain suffix match

Rule type
DOMAIN-SUFFIX
Parameter
metrics.example.com
Policy
REJECT
Match scope
metrics.example.com and its subdomains

Use a suffix rule only after confirming the entire domain branch serves the same purpose.

DOMAIN-SUFFIX,example.com,REJECT matches example.com and subdomains such as api.example.com. It is not a substring match, so notexample.com should not match. Don't use *.example.com in place of the suffix parameter; enter the bare domain as required by the rule syntax.

3. Rules are evaluated from top to bottom: exceptions first, FINAL last

Rule order directly affects the outcome. For a given connection, the first matching rule determines how it is handled; a more specific rule farther down does not automatically take priority. Put allowed exceptions before the reject rule they would otherwise match. Broad IP or region rules and FINAL usually come after the relevant domain rules.

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

This snippet demonstrates rule order only: keep.metrics.example.com matches the exact exception first, while the rest of the metrics.example.com domain branch is rejected. FINAL,DIRECT is included only to make the example self-contained. Keep your existing fallback policy in a real configuration; don't route all unmatched traffic directly just to add a block rule.

Rule positionTypical issueHow to fix it
Reject rule comes after FINALThe connection was already handled by the fallback ruleMove the reject rule above FINAL
Exception comes after suffix rejectThe exception hostname matches REJECT firstMove the exact exception above the suffix rule
Broad allow rule comes before rejectThe destination matches the allow policy firstCheck the match log and reorder overlapping rules

Takeaway: check the first matching rule before adding another

If an earlier rule already handles the target connection, adding the same REJECT rule again won't change the outcome. Check the active configuration and the match position first, then move the rule or narrow its conditions.

For an IP address, syntax such as IP-CIDR,192.0.2.0/24,REJECT,no-resolve illustrates how an address range can be matched; this range is a documentation example. no-resolve means the IP rule won't trigger a DNS lookup for that rule. It does not disable DNS on the device. A shared IP may host unrelated domains, so don't reject an entire address range just because domain blocking had no effect.

4. Domain rules can't distinguish paths on the same host or control in-app layouts

Suppose the article uses api.example.com/article and the promotion uses api.example.com/promotion. Both use the same hostname, so DOMAIN and DOMAIN-SUFFIX cannot reject just the latter path. Setting api.example.com to REJECT may also block the article, login state, and comments API.

How content is deliveredWhat domain rules can doWhat they can't guarantee
Assets loaded from a separate hostnameReject new connections to that hostnameThat the app removes the resulting blank space
Different paths on the same hostnameHandle the hostname as a wholeSelecting a specific path with a domain rule
Promotion and main content in the same responseReject the entire connectionSelecting part of the response content
Locally cached or bundled contentMatch anything when there is no new connectionThat already displayed content disappears immediately

HTTPS usually hides URL paths and response bodies. Even when a rule can identify the destination domain, that does not mean it can read every resource in an encrypted connection. Domain-level REJECT can block a host without decrypting its content, but its scope is limited to the connection. Path-level handling, response rewriting, and hiding page elements are not domain-rule capabilities.

5. Add and test one rule at a time, with a way to roll back

Test with a configuration that already works. This guide assumes you have your own provider and subscription; it does not provide or recommend connection services. If the resource you're testing is normally accessible directly, keep your existing connection setup and observe only the effect of the new rule.

  1. Back up the current configuration. In Config, confirm which file is active, then save a copy or record its original contents. Don't overwrite the entire file with the example snippet.
  2. Set a consistent routing mode. On Home, confirm the connection is enabled, set Global Routing to Config, and make sure the configuration you edited is active.
  3. Add an exact rule. In the configuration's [Rule] section, start with a rule such as DOMAIN,ads.example.com,REJECT. Replace the example hostname with the target hostname from your logs, and place the rule above relevant broad rules and FINAL.
  4. Save and make a new request. Reopen the target page or app. If needed, reconnect so the new request is evaluated against the updated configuration. Existing long-lived connections and local caches are not reliable evidence on their own.
  5. Check connection logs. Find new requests to the target hostname and confirm the actual policy is REJECT. Also check essential features such as login, article content, images, and playback.
  6. Roll back if something breaks. Remove or disable the rule you just added, then test again. If the feature works again, decide whether to add an exact exception, narrow the rule to DOMAIN, or stop blocking that hostname altogether.

If automatic connection is enabled, also check Settings → On Demand so a connection being restored or its state changing during a test doesn't go unnoticed. On Demand controls when a connection starts; it does not change REJECT match priority. Troubleshoot them separately.

6. Troubleshooting: no match, content still visible, or a feature stops working

I added REJECT. Why does the webpage still open?

First check whether you rejected the webpage's hostname or the hostname of an asset it loads. If only an asset domain is rejected, the main page may still open as expected. Then confirm Global Routing on Home is set to Config, the right configuration is active, and the rule is above FINAL. Finally, check the actual policy for a new connection instead of judging by whether the whole page opens.

The log shows REJECT. Why is the app still showing the old content?

Reopen the target page and check whether it makes new requests. Downloaded images, preloaded content, and assets bundled with the app may remain visible. The app may also switch to another hostname. Compare request times and destination domains; don't widen the block just because content is still on screen.

I can't log in after adding a rule. How do I recover?

First remove the rule you added most recently, then try logging in again. If login works, the rule may have covered an essential endpoint. Compare the hostname logs from before and after login, and narrow the suffix rule to an exact hostname. Add an exact exception before the reject rule only when you've confirmed that hostname needs to be allowed.

Will switching to a different proxy protocol make REJECT more precise?

No. Switching to Shadowsocks, VMess, VLESS, Trojan, Hysteria2, or WireGuard does not add content-aware filtering. REJECT matches depend on traffic being handled by the rules, the destination information available, and rule order. Keep your connection setup unchanged while testing rules so you can isolate the cause.

Keep a rule only if three conditions are met: the new request to the target actually matches, the intended resource is restricted, and essential features remain unaffected. If a domain can't separate content you want to keep from content you want to block, recognize the limits of hostname-level rules rather than stacking broader reject rules.