V2Ray Routing Rules: Domain, IP, GeoSite Syntax and Priority

Learn domain, full, and regexp matching, IP and GeoIP rules, GeoSite lists, rule order, and how domainStrategy affects routing.

At a glance

This guide is for users who can connect to a server and want to fine-tune routing rules. First check whether the core receives a domain name or an IP address, then choose the right match syntax, order the rules, and use logs to verify the outbound. The JSON snippets here are core configuration, not subscription data. Understanding the difference can help diagnose issues such as added rules having no effect, private-network traffic going through a proxy, or category rules failing to load.

1. How routing rules choose an outbound

v2rayN provides the client interface; the V2Ray or Xray core handles matching and forwarding. VMess and VLESS are protocols used to connect to servers—they do not determine which outbound a website must use. During connection handling, routing uses details such as the destination domain, destination IP, port, and inbound tag to select an existing outbound.

Accept inbound Read destination Match in order Select outbound Connect

routing.rules are checked from top to bottom. The first matching rule selects the outbound; the core does not keep searching for a “more specific” match. If no rule matches, the first entry in the outbounds array is usually used as the default. Check the default outbound too—not just the last rule.

2. Matching boundaries for domain, full, and regexp

domain can refer to the field in a rule or to a prefix on a field value; these are different things. The field holds domain conditions, while the prefix defines how they match. To cover a root domain and all its subdomains, use domain:. To match only one exact hostname, use full:.

SyntaxHow it matchesBoundary example
example.comMatches a substring when no prefix is usedMay also match notexample.com
domain:example.comMatches the root domain and its subdomainsMatches img.example.com, but not notexample.com
full:api.example.comMatches the exact domainDoes not match img.api.example.com
regexp:^api[0-9]+\\.example\\.com$Regular expression; shown here as written inside a JSON stringMatches api12.example.com, but not api.example.com

Domain rules do not match URL paths. For https://api.example.com/v1/status, the destination domain is api.example.com; don't include the scheme, path, or query parameters in the domain field. HTTPS paths are not conditions that ordinary routing rules can inspect directly.

{
  "type": "field",
  "domain": [
    "full:api.example.com",
    "domain:static.example.net",
    "regexp:^edge[0-9]+\\.example\\.org$"
  ],
  "port": "443",
  "outboundTag": "proxy"
}

This rule means that any one of the three domain conditions must match, and the destination port must be 443 for traffic to use proxy. The dot in a regular expression must be escaped. Inside a JSON string, the backslash must also be escaped, so write \\.. In a client's plain-text domain field, you usually only need \.. Don't mix up the two input formats.

3. When to use IP, CIDR, and GeoIP

The ip field matches the destination IP. It accepts individual addresses, CIDR ranges, and geoip: categories. This is the address the request is trying to reach—not your computer's network interface address or the server's address. IP rules can still match when an app connects directly to an IP without resolving a domain name.

Explicit IP ranges

Single address
192.168.1.10
IPv4 range
192.168.0.0/16
IPv6 range
fc00::/7
Data requirements
Does not require geographic database files

Best for LANs or fixed service ranges with known boundaries.

GeoIP category rules

Private address category
geoip:private
Regional IP category
geoip:cn
Common data files
geoip.dat
What to check
The category exists and its data can be read

The category's coverage depends on the dataset; it does not reflect real-time network location.

{
  "type": "field",
  "ip": [
    "127.0.0.0/8",
    "10.0.0.0/8",
    "172.16.0.0/12",
    "192.168.0.0/16",
    "::1/128",
    "fc00::/7"
  ],
  "outboundTag": "direct"
}

The snippets above show explicit direct-routing ranges; they are not a complete list of special-use addresses. If you use geoip:private, check what the current dataset includes. For a company network, it's safer to specify the ranges actually in use rather than assume they belong to a “private” category.

4. Using GeoSite categories and data files

Use geosite: in the domain array to reference a domain collection; use geoip: in the ip array. These prefixes are not interchangeable. geosite:cn references the collection named cn in the dataset; it does not simply mean every domain ending in .cn.

{
  "type": "field",
  "domain": [
    "geosite:cn"
  ],
  "outboundTag": "direct"
}

If the core exits as soon as it loads the configuration, check the logs for resource-loading errors before switching servers repeatedly. A speed test cannot confirm that routing is correct if the category rules never loaded. Temporarily remove the problematic category reference and keep one explicit domain rule to help distinguish configuration errors from network problems.

5. How domainStrategy affects IP rules

routing.domainStrategy controls whether routing resolves a domain target to an IP for matching. It is not the same as the DNS policy used by the final outbound. It also cannot recover a domain name that the app has already discarded: if the app submits only an IP, using domain rules may require inbound sniffing and other conditions—and sniffing does not work for all traffic.

StrategyHow domain targets are handledTypical effect
AsIsDoes not resolve domains to IPs for routing matchesDomain targets generally cannot be routed by IP rules alone; targets that are already IPs can still match
IPIfNonMatchMatches using the available target information first; resolves the domain and retries if nothing matchesIf a fallback rule matches on the first pass, the retry resolution is never triggered
IPOnDemandResolves the domain when a condition requires the destination IP during matchingAn earlier IP rule may match first and take precedence over later domain exceptions

A common pitfall is setting IPIfNonMatch and then adding a final proxy rule that matches all TCP and UDP traffic. Since that fallback matches on the first pass, domain targets never reach the “resolve IP if nothing matches” step. As a result, an earlier geoip:cn rule may never get a chance to check the resolved address.

In short: choose a fallback approach before choosing a resolution strategy

If you want IP categories to handle domains that did not match, with IPIfNonMatch you can rely on the first outbound as the fallback instead of adding a final rule that always matches on the first pass. With IPOnDemand, put domain exceptions that must take precedence before broad IP categories.

DNS results directly affect IP category matching here. If the same domain goes direct one day and through a proxy the next, check both its resolved addresses and the category data before assuming rule order has failed. For more on DNS and routing fields, see the configuration reference.

6. Routing example, ordered by priority

This example uses IPOnDemand to show the order clearly: specific domain exceptions, private-network direct routing, domain categories, IP categories, then proxy. This is only a routing object to merge into an existing configuration. The configuration must already have outbound tags named proxy and direct, and the required category data must be available.

{
  "routing": {
    "domainStrategy": "IPOnDemand",
    "rules": [
      {
        "type": "field",
        "domain": [
          "full:api.example.com"
        ],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "geosite:cn"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": [
          "geoip:cn"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

api.example.com is a reserved example domain used to explain the rules, not a service for testing availability. It's placed first, so it uses the proxy even if a later IP category could match. In actual use, replace it with a real business domain that needs a fixed outbound, or remove the rule.

  1. Keep a copy of your current configuration: Export it from the client and note which routing scheme is enabled, so you can restore it if changes go wrong.
  2. Check the actual tags: Look at tag values under outbounds in the generated configuration and confirm they match the example. Your client may use different tag names.
  3. Merge only the routing object: Don't replace the entire configuration with this snippet, or you'll lose essential sections such as inbounds, node outbounds, and DNS.
  4. Save and enable the configuration in the UI: v2rayN menu names vary by version. A common path is Settings → Routing settings. After adding rules, make sure the intended routing scheme is enabled.
  5. Start a fresh test connection: After saving, reload or restart the core as prompted by the client, then close existing browser connections before testing. Existing connections may not be routed again.

7. How to verify that a rule actually matched

A website loading only confirms that the connection succeeded; it doesn't confirm that traffic used the intended outbound. To verify routing, record the destination, protocol, matched outbound, and test time. Start with one exact domain and a minimal test, then add category rules gradually. This makes problems easier to isolate than changing a dozen rules at once.

  1. Confirm traffic reaches the core: Check whether your browser follows the system proxy. For a command-line test, use curl --proxy socks5h://127.0.0.1:10808 https://example.com/ -I. Replace 10808 with the SOCKS inbound port actually used by your client.
  2. Preserve the domain as the target: The command above uses socks5h, which sends the domain to the proxy for resolution. If the app resolves the domain locally and submits an IP instead, the conditions for testing domain rules have changed.
  3. Check the core logs: Look for the destination address and outbound tag; log formats vary by core version. If access logging is disabled, enable it temporarily according to your version's settings. Don't assume no traffic occurred just because nothing was logged.
  4. Run three comparison tests: Test one explicit domain exception, one reachable private-network address, and one ordinary public domain. Record the expected and actual outbound for each. Use port 80 or 443 for the private-network service, as appropriate.
  5. Clear the test conditions: Close existing connections and retry; restart the test app if needed. When finished, restore the usual log level to avoid accumulating detailed access logs.

Why doesn't a full rule proxy traffic to subdomains?

full:example.com matches only that exact hostname. To include www.example.com, use domain:example.com, move the rule above any broad direct-routing rule, and start a new connection.

Why is it harder to match when both domain and IP are set?

The two fields in one rule are not alternatives. If you want “these domains or these IPs” to go direct, split them into two rules and set the same outboundTag on each.

What should I do if the core won't start after I add a GeoSite category?

Check the first loading error and verify the resource path for geosite.dat and the category name. Remove the category first and use a full: rule to confirm the core runs, then restore a valid data file and category.

Can I use the entire desktop configuration as-is on Android?

v2rayNG uses the Xray core, while v2flyNG uses the v2fly core. Their basic matching syntax is similar, but outbound tags, resource file locations, and import methods depend on the client. Check which fields the selected core supports before migrating routing snippets. Don't replace the entire runtime configuration.

When troubleshooting, check in this order: target information, rule order, resolution strategy, data files, and actual outbound. First verify that one precise rule works, then expand to domain collections and IP categories. This is usually more reliable than repeatedly replacing the entire set of rules.

V2Ray Client Downloads