At a glance

This guide is for users who have imported a subscription and can connect to a server, but aren't sure which requests go through the proxy. First, distinguish domain lists from IP databases. Then order rules as specific exceptions, general rules, and the default route. Finally, check the generated configuration and connection logs in v2rayN or v2rayNG. The examples use Xray routing fields; the native JSON snippets are not universal client import files.

Routing: First Confirm Traffic Reaches the Core

v2rayN is a desktop GUI client, while v2rayNG is an Android client that uses the Xray core. The interface manages servers and settings; the core evaluates routing rules. Protocols such as VMess and VLESS determine how a proxy connection is established, not whether a particular site should connect directly or through a proxy.

App request Enters the core Target identified Rules matched Outbound selected

The system proxy affects only apps that honor that setting. TUN or Android's VPN-based capture can handle more traffic, but app exclusions, routing settings, and system permissions still apply. If the browser never hands its connection to the client, changing ten geosite rules won't affect its route.

geosite and geoip: One Matches Domains, the Other IPs

geosite.dat contains domain collections organized by tag, while geoip.dat contains IP range collections organized by tag. References such as geosite:cn and geoip:cn point to these collections; they aren't network lookup commands and don't mean the client automatically downloads the latest lists.

Domain Rules: geosite

Data file
geosite.dat
Common references
geosite:cn
Rule field
domain
Matches
Target domain visible to the core

Whether a tag exists depends on the rule file in use; categories can cover different ranges across datasets.

Address Rules: geoip

Data file
geoip.dat
Common references
geoip:cn
Rule field
ip
Matches
Target IP or resolved route address

An IP's registered location is only a routing signal; it doesn't identify the website operator's location or the language of its content.

For explicit domain rules, full:example.com matches only that exact domain, while domain:example.com matches it and its subdomains. A plain string without a prefix is generally matched as a substring, which can include unrelated domains. Use full: or domain: for precise exceptions.

If rule resources are missing, logs may report that geosite or geoip couldn't be loaded, or that a tag wasn't found. Update resources through the current client's resource update feature, then confirm the running core is reading from the updated location. Don't just copy files into an arbitrary download folder, and don't assume geosite:some-tag is supported by every dataset.

Rule of thumb: Prefer a domain exception when you know the domain

A single website may use CDN addresses in multiple regions. If you want to change the route for one site, a domain rule is more precise than sending an entire shared IP range direct.

Rule Order: The First Match Wins; Check the Default Route Separately

Standard routing rules are checked from top to bottom in array order. The first match selects the outbound, and later rules don't override it. Within one rule, different condition fields generally all need to match; multiple domain entries in the same domain array are alternatives, so any one match is enough.

  1. Specific site exceptions: Put sites that must use a proxy before broad direct-connection rules.
  2. LAN and private addresses: Route requests to routers and local services directly. The actual coverage depends on the private address ranges in use.
  3. Common domain collections: For example, route geosite:cn directly.
  4. IP geolocation rules: For example, route geoip:cn directly, and consider the domain strategy to understand when the rule applies.
  5. When no rule matches: In a native configuration, the first outbound is used. A client may also generate additional fallback rules.

Don't put a catch-all rule that proxies all TCP and UDP traffic first. It will match ordinary connections before the direct rules can run. A less obvious issue: with IPIfNonMatch, a broad fallback rule that already matches can also prevent the “resolve the domain after no match” step.

domainStrategy: Controls Domain Resolution During Routing

This section covers routing.domainStrategy. It controls how domains are handled during route matching. It isn't the identically named setting inside a direct outbound, and it can't by itself determine which outbound handles DNS requests.

StrategyBehavior during routingNotes
AsIsMatch the original target; don't resolve domains specifically for IP rulesIP rules can still match when the target is already an IP address
IPIfNonMatchIf a domain request doesn't match on the first pass, try resolving it and match againUseful when you want domain rules first, with IP geolocation as a fallback
IPOnDemandTry resolving when a rule encountered during matching requires an IP addressAn earlier IP rule may trigger a DNS lookup

Suppose a domain doesn't appear in any domain collection, but resolves to an address in geoip:cn. If no earlier rule matches, IPIfNonMatch can resolve the domain and then match the direct rule. AsIs won't proactively perform that conversion for the domain.

DNS results affect IP rules. Resolvers may return different CDN addresses, and IPv4 and IPv6 addresses may have different geolocation results. If a site sometimes connects directly and sometimes through a proxy, check the actual destination address, DNS settings, and matched rule together rather than assuming geosite is broken.

Native Configuration Example: Domains First, IP Rules as a Fallback

The snippet below shows only the routing section. Use it as a reference when inspecting generated configuration or editing a native config. It assumes the configuration already has proxy and direct outbounds, with proxy as the first outbound. example.com and example.org are documentation examples; they don't imply that either domain needs a particular route.

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "domain": ["domain:example.com"],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "domain": ["full:example.org"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["geosite:cn"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:cn"],
        "outboundTag": "direct"
      }
    ]
  }
}

This snippet doesn't include server credentials, inbound listeners, DNS, or complete outbound definitions, so it can't replace an entire client configuration. A GUI's “import routing rules” feature may use its own data format; JSON isn't necessarily something you can paste directly into it.

v2rayN and v2rayNG: Apply Rules in the GUI

Menu names can vary by version, sometimes adding labels such as “Settings” or “Custom.” The steps below describe common entry points and workflows in the Chinese-language interface. If the labels differ, look for the equivalent feature. Don't assume a routing file exported from the desktop client is a universal format for Android.

v2rayN: Copy a Profile, Then Adjust Rule Priority

  1. Open “Settings” → “Routing Settings.” Keep your current working profile, then copy it or create a test profile.
  2. In the rule editor, choose a domain or IP condition and enter items such as domain:example.com, geosite:cn, or geoip:cn. Select the proxy or direct option available in the interface for the outbound.
  3. Move specific domain exceptions above broad collections. If the interface has a domain strategy option, check how it affects routing.
  4. Save the profile, then enable it in the routing selector on the main screen. Saving without selecting the profile usually won't change the active connection.
  5. Reconnect for testing, then use the logs or generated configuration view to check rule order, the default outbound, and the actual tag.

v2rayNG: Separate Core Routing from App Routing

  1. Open the side menu and go to “Settings” → “Routing Settings.” Check the current routing mode, domain strategy, and the sections for proxy, direct, and block rules.
  2. Add domain entries in the relevant custom rule field. Support for full geosite references, rule ordering, and JSON editing depends on the current version's interface.
  3. If the target app isn't included in VPN traffic capture, adjust the app routing settings first. That's a separate setting from geosite domain routing.
  4. After saving, disconnect and reconnect, then start a new connection. Existing long-lived connections may continue using their original outbound.

If you need precise per-rule ordering but the current version only offers text fields grouped by category, check the order of the rules it generates. Separate “proxy domains” and “direct domains” fields don't reveal which one takes priority when rules conflict.

Verify Routing: Check the Outbound in Logs, Not Just Whether a Page Loads

A page loading only confirms that the connection succeeded; it doesn't prove the expected outbound was used. Choose three test targets: a LAN address, an explicit domain exception, and an ordinary domain that matches no collection. Change one thing at a time, start a new connection, and record the target and outbound.

10808
Example local SOCKS test port
443
HTTPS test target port
192.168.0.0/16
One common private IPv4 range

The 10808 above is an example, not a guarantee of the port currently used by your client. Check the actual listening port first. If curl is available on your system, run the request below in a desktop terminal to send the target domain to the core through the SOCKS entry point, reducing differences caused by early name resolution in the app.

curl --proxy socks5h://127.0.0.1:10808 --head https://example.com

Unlike test methods that pass only a resolved IP, socks5h passes the domain to the proxy for resolution. The goal isn't to compare speed, but to make the target in the logs match the rule input. If the logs lack detail, you can temporarily increase the log level. Restore it afterward, and remove subscription URLs, server credentials, and personal browsing records before sharing logs.

Practical tip: Start with one reproducible domain exception

First make one known domain consistently match the intended outbound, then add geosite and geoip rules. If even a single rule has no effect, check the traffic entry point, active profile, and outbound tags before adding more categories.

FAQ: Rules Saved, but Traffic Still Isn't Routed as Expected

Why does a domain set to direct still use the proxy?

First confirm that the profile you edited is active, then check for a broad proxy rule above the direct rule. Disconnect existing connections and try again. If the logs show only the target IP and not its domain, also check how the app resolves names and whether traffic sniffing is enabled.

Why do some sites in China still use the proxy after I added geoip:cn?

Check whether routing.domainStrategy is set to AsIs, and whether the actual resolved address is in the IP database you're using. With IPIfNonMatch, also remove any fallback rule that matches earlier, or use an explicit direct domain rule instead.

Will updating my subscription overwrite custom routing rules?

A standard server subscription usually updates server entries, while routing is typically managed separately by the client. Importing or replacing a full configuration may change routing. Keep a copy of the current profile before updating, then check the active route afterward. These are two different import operations.

How do I fix a missing geosite tag error?

Check the tag name in the error, then update the rule files using the client's resource update feature and confirm the core is reading the updated files. If the dataset doesn't contain that tag, use a category it actually provides or start with an explicit domain list instead.

Why configure core routing if TUN is enabled?

TUN determines how more app traffic enters the client; core routing determines which outbound handles that traffic. First confirm traffic is getting in, then test LAN direct connections, domain exceptions, and the default proxy route separately. Successful capture doesn't mean routing is correct.