For users who have imported a subscription and want to customize routing in v2rayN. Start by distinguishing domain matches from IP matches, then learn how first-match order, DNS resolution strategy and outbound tags work. The JSON snippets are core configuration examples, not complete, runnable configs. Use them to diagnose two common issues: rules that never take effect and exceptions overridden by broader rules.
1. Routing rules: Choose the outbound for each request
A subscription provides connection settings for nodes; routing determines which requests use them. VMess and VLESS are connection protocols, not routing matchers. Switching a node to VLESS does not automatically change whether a site connects directly or through a proxy.
In common V2Ray and Xray routing configurations, routing.rules is an ordered array. Each rule checks conditions such as the destination domain, destination IP, port or inbound tag. When a rule matches, outboundTag points to a configured outbound. Tags are just names in the configuration; proxy and direct are not built-in outbounds.
- Domain-based request: If the core receives
www.example.com, it can check domain rules directly. - IP-based request: If the core only receives the destination address, there may be no domain available to match. Whether the domain can be recovered depends on the inbound, sniffing and DNS settings.
- Outbound reference: The
outboundTagin a rule must match ataginoutbounds, including letter case.
2. domain, full and regexp: Choose a prefix for the match you need
domain is both a rule field and a possible matching prefix in a field value. The strings in the table below belong in the "domain": [...] array. Don't include the URL scheme, path or query string. Routing matches domain names, not browser address-bar URLs.
| Syntax | What it matches | Typical boundary case |
|---|---|---|
full:example.com | Exact hostname only | Matches example.com, not www.example.com |
domain:example.com | A domain and its subdomains | Matches example.com and a.example.com, not notexample.com |
example.com | Substring match | Broader than domain-boundary matching; may match notexample.com |
regexp:^api[0-9]+[.]example[.]com$ | Regular expression match | Matches api1.example.com, not api.example.com |
geosite:cn | Domain group in a data file | Depends on whether the local data file provides the cn tag and what it contains |
Use full: to proxy a single hostname. Use domain: to apply the same rule to a site and its subdomains. A plain string is for cases where you explicitly want a substring match; it is not shorthand for an exact domain. Don't write domain:*.example.com either: this syntax does not support wildcards.
{
"type": "field",
"domain": [
"full:login.example.com",
"domain:example.net",
"regexp:^api[0-9]+[.]example[.]com$"
],
"outboundTag": "proxy"
}
The three array entries above are OR conditions: any one matching domain is enough. The regular expression uses [.] for a literal dot, avoiding confusion from JSON backslash escaping. If you use \. in a regex instead, write it as \\. in a JSON string. The leading ^ and trailing $ anchor the match to the entire string.
3. ip, geoip and geosite: Keep address and domain groups separate
The ip field accepts IP addresses, CIDR ranges and geoip: groups. The domain field accepts domain matchers and geosite: groups. These group types are not interchangeable. geoip:cn matches an address classification; it does not mean all Chinese-language websites. geosite:cn is a domain list, and those domains are not guaranteed to always resolve to addresses in the same region.
{
"type": "field",
"ip": [
"192.168.0.0/16",
"10.0.0.0/8",
"geoip:private"
],
"outboundTag": "direct"
}
This snippet routes private-network destinations directly. The first two ranges may overlap with geoip:private, so a real configuration usually only needs the specific ranges or the group. To route domains and IP addresses in mainland China directly, use two rules: one with domain, another with ip. Don't put both fields in one rule expecting them to work as OR conditions.
- Multiple values in one field are usually OR conditions: An
iparray can list multiple ranges; a match on any one is enough. - Different condition fields in one rule are usually AND conditions: For example, combining
domainandportrequires both the domain and destination port to match. - Groups depend on local resources: Common configurations read
geosite.datandgeoip.dat. A missing tag, incorrect resource path or missing file can prevent the core from starting. - Group contents can change: After a resource update, a domain or address may be classified differently. When troubleshooting, note the resource update date, not just the client version.
4. First match wins: Put exceptions before broad rules
Rules are checked in array order, and the first match determines the route. More specific rules do not automatically get higher priority. If you put domain:example.com for direct access before full:api.example.com for proxy access, the broader rule takes precedence.
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": ["full:api.example.com"],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": ["domain:example.com"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
This configuration preserves a proxy exception for one hostname, then routes the entire domain directly, and finally sends remaining TCP and UDP requests through the proxy. It shows only routing; you need existing outbounds tagged proxy and direct to use it. If no rule matches, the core commonly uses the first outbound. Don't assume the default route based on a tag's name.
- List explicit exceptions. For example, login endpoints, internal services or domains that must use a specific exit.
- Add group rules. Then add verified
geositeandgeoipcategories. - Set a fallback. Check the final catch-all rule or first outbound to avoid sending unmatched requests directly by accident.
- Check the generated order. The client may generate both preset and custom rules, so the UI list may not show the final, complete array.
Port conditions also affect what a rule matches. For example, adding "port": "443" to a domain rule only handles requests to destination port 443; connections to port 80 on the same domain won't match. If you want to route an entire site through the proxy, don't add a port restriction unintentionally.
5. domainStrategy: When domain names are resolved to IP addresses
Even with a correctly written domain rule, an IP rule may not match because of when resolution happens. routing.domainStrategy controls whether domain names are resolved to addresses during route matching; it does not guarantee that DNS queries will go through the proxy. Check core DNS, outbound resolution and client DNS settings separately.
AsIs: Match the information already available
- Config field
- routing.domainStrategy
- Value
- AsIs
- Domain-based request
- Does not actively resolve an IP for route matching
- IP-based request
- IP rules can still match
Suitable when domain rules do most of the work and you want to minimize resolution during routing.
IPIfNonMatch: Resolve only if no rule matches
- Config field
- routing.domainStrategy
- Value
- IPIfNonMatch
- When it triggers
- A domain destination doesn't match any existing rule
- What happens next
- Resolve the domain, then try matching again
If a broad fallback rule has already matched, the request won't reach the resolution-on-no-match stage.
Another common value is IPOnDemand: resolving the destination domain can be triggered when a rule requires an IP during matching. Putting an IP rule near the top may therefore trigger DNS queries earlier. Decide whether domain-based or address-based classification should take priority before changing rule order; switching strategies isn't a universal fix.
- Prioritize domains: Express your needs with
full:,domain:andgeosite:first. - Use addresses as a supplement: If you need to match resolved addresses, check that the strategy allows resolution and see what DNS actually returns.
- Watch for the fallback: With
IPIfNonMatch, a domain request may match a final catch-all rule directly, skipping the second IP-based match.
6. Verify in v2rayN: Inspect the generated config and connection logs
Back up your current routing setup, then open routing settings in v2rayN to edit the rules. Menu names can vary between desktop interfaces; use the routing settings and rule editor shown in your current version. The JSON in this article shows V2Ray/Xray core fields; don't paste it as-is into a field that only accepts a list of domains.
These numbers describe port usage, not test results. Port 443 does not mean all web traffic, and port 53 does not cover all encrypted DNS. When routing by port, account for the actual transport; a port number alone doesn't identify an application's purpose.
- Check the input format. JSON uses straight double quotes and has no comments or trailing commas. Keep core field names unchanged.
- Check which core is running. Confirm that the expected core is selected and inspect the rule syntax the client actually generated. Don't mix in fields from another configuration format.
- Check tags and resources. Verify that
outboundTagexists and that group tags can be loaded. Fix core startup errors before testing routing. - Reconnect. After saving and applying the routing changes, close old connections in the test app and make a new request. Existing long-lived connections won't switch outbounds just because the rule list changed.
- Check access logs. In the available log details, inspect the destination domain or IP, destination port, inbound tag and outbound tag. Raise the log level temporarily if needed, then restore it after testing.
To test domain rules, prepare at least three cases: an exact exception, api.example.com; another host on the same domain, www.example.com; and a destination outside that domain. The first two distinguish full: from domain:; the third checks the fallback. Example domains are for illustrating match boundaries only. For connection tests, use domains you are authorized to access that actually host a service.
7. Common issues: Check overrides, address input and group errors
Why does a proxy rule still connect directly?
Check whether a broader direct rule appears earlier. Move the specific exception above the broad group, apply the changes and reconnect, then verify the outbound tag in the logs. If the generated order differs from the UI, check whether preset rules match first.
My domain rule is in place, but the logs show only an IP. What should I do?
First check whether the app resolves the domain locally and whether the inbound passes the domain through. Then check the current core's sniffing settings. Sniffing can only extract information from supported traffic and cannot recover the domain for every connection. For a known, fixed internal destination, use an explicit IP or range rule instead.
The core fails to start after I add geosite. What should I check?
Start with the resource file path and tag name shown in the logs. Confirm that the current data file includes the tag, and update it through the resource update option provided by the client if needed. Temporarily test basic routing with a single full: rule, then restore the group. This avoids changing multiple variables at once.
Rules stop working after I switch nodes. Does the protocol not support routing?
Check the generated configuration first; don't assume VMess or VLESS is the cause. Confirm that the rules still reference the correct proxy outbound after switching, that the routing setup is still selected and that the client hasn't switched to another custom configuration. A failed node connection and a routing rule selecting the wrong outbound are separate issues; check their logs independently.
A reliable workflow is to verify the outbound with one exact domain first, then expand to subdomains or groups, and add IP-based conditions and a fallback last. Change one type of condition at a time, and keep a routing setup you can restore. For more on the basics, see Concepts at a Glance. To troubleshoot DNS and routing together, see Advanced Setup.