Configuration Reference / v2rayN · v2rayNG

Advanced V2Ray Configuration Guide

Subscription Groups, Routing, DNS, and TUN

Get a working connection first, then adjust network behavior one setting at a time. This guide focuses on v2rayN on desktop and v2rayNG on Android. Check v2flyNG's core capabilities and options separately.

Rule order Resolution path Traffic interception Outbound tags

This page is a reference guide, not a first-connection walkthrough. If you haven't installed the client, imported a configuration, and verified a connection, start with Getting Started and test the default settings first. See the client download page for installers and architecture options. Client interfaces change over time, so this guide keeps core parameter names intact; menu locations may vary. Configurations for different cores are not interchangeable.

Subscription Groups and Server Filtering

Separate subscription sources, server entries, and the active configuration

A subscription group stores a configuration source and its update options. A server entry stores connection parameters, while the active configuration is the entry used by the core at startup. These are separate objects. Switching groups usually changes which entries are shown; it may not change the server in use. Selecting a row doesn't necessarily make it active, either. After a change, check the client's current-server indicator, then disconnect and reconnect before judging the new configuration.

When organizing subscriptions, create a group for each source, such as “Primary,” “Backup,” or “Manual.” Enter a label and subscription URL in v2rayN's subscription group settings or v2rayNG's subscription settings, then update that group. A share link contains one or more specific connection profiles; it doesn't update itself over time. For the difference between import methods, see Share Links vs. Subscription URLs. Don't paste a single-server link into a subscription URL field.

Filter by remarks, not protocol fields

Server filters affect the list, not network routing. Searching for “backup” narrows the visible entries; it won't automatically send certain websites through a backup server. Start with ordinary keywords to see what matches. Use regular expressions only if the interface explicitly supports them. For example, ^(办公|备用)- matches remarks that begin with one of the specified prefixes; don't assume every search box accepts regex. Check how include and exclude filters combine by inspecting the actual list, so you don't hide every usable entry.

Use stable remark prefixes for filtering rather than temporary latency values or changeable list positions. Subscription updates can change remarks, order, and entry counts, and entries with the same name may use different addresses, ports, or transport settings. To check whether entries are duplicates, compare the server address, protocol, port, and transport parameters—not just the name. Usernames, IDs, and keys are sensitive connection details; redact them from screenshots and logs before sharing. Remove access tokens from subscription URLs, too.

ActionWhat changesWhat to check
Switch subscription groupWhich entries appear in the listWhether the active server is still the same entry
Update subscriptionServer configurations in the groupWhether manual changes were overwritten
Filter by remarkWhich servers are visibleWhether the filter field supports regex
Set as active serverConfiguration used for the next connectionWhether the core has reloaded

If an update fails, keep the existing entries first

Before updating, check whether the operation deletes existing entries before importing new ones. Retention behavior varies by client and update method, so don't rely on assumptions. Export important manual entries separately instead of storing them in a group that may be rebuilt. If the list is empty after an update, check whether the response is in a subscription format the client supports, whether the URL has expired or returned a login page, and whether the request can reach the source over the available network.

If you get stuck in a loop such as “The current proxy is unavailable, so the subscription can't be updated through it,” distinguish the subscription fetch path from the server connection path. Use a direct update only when the source permits it and your local network can reach it. Avoid repeatedly changing global settings and losing the original state. Note whether the failure occurs during DNS resolution, connection setup, or content parsing. Restore the previous configuration before retrying one change at a time. A successful update only means the configuration was retrieved; it doesn't mean every entry can connect.

Set up a repeatable check: confirm the group name, clear filters, compare addresses and key parameters before and after an update, then select the active server manually. Test one real webpage before running bulk tests. Tests generate connections and traffic, and running too many at once may trigger server-side limits. Keeping a few verified backups makes recovery easier than relying on list order.

Routing Rules in Practice: Match First, Then Choose an Outbound

Set rule order and the default outbound

Xray routing rules are generally checked from top to bottom, and a match is sent to the specified outbound. Order matters more than a tidy-looking list: put exact domains, specific app entry points, and special destinations before broad region-based rules. Before editing, list the outbound tags already defined and confirm that direct, proxy, and block actually exist. Tags are case-sensitive references, not reserved keywords. Using an undefined tag won't create a connection for you.

Within a rule, different condition fields usually all need to match; multiple values in the same field usually mean any one of them can match. For example, specifying both domain and port means the domain and port conditions must both match—not either one. If you need “send this domain through the proxy, and also proxy a separate set of ports,” two rules are clearer. The longer the rule, the more important it is to describe its conditions in one plain sentence before writing the configuration.

Start with one exact-domain rule

This is a partial Xray routing snippet. It assumes the configuration already defines the proxy and direct outbounds. The example sends a documentation test domain through the proxy, then handles domains in mainland China and private addresses. full: matches an exact domain; domain: matches that domain and its subdomains. The example domains illustrate syntax only. Use your actual destinations in a real configuration; don't use these examples to test service availability.

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

geosite and geoip reference rule data; they don't perform live online lookups. Missing data files, unsupported category names, or outdated data can cause loading errors or unexpected matches. Updating the client and updating rule data are separate tasks. To troubleshoot, first validate the routing structure with a single full: rule, then restore the category references. Don't change the core, data files, and every rule all at once.

When domainStrategy resolves domains

AsIs doesn't resolve a destination domain just to evaluate routing rules, which suits setups based mainly on domain rules. IPIfNonMatch tries to resolve the domain if no domain rule matches, then checks the resulting address. IPOnDemand may resolve a domain as soon as a rule requires an IP. These options control behavior during routing; they don't directly choose the DNS server used or determine address selection when the outbound connection is made.

If an app gives the client an IP address directly, domain rules may have no domain to match. Traffic sniffing can identify domain hints in some HTTP or TLS requests, but it can't recover the original domain for every protocol. Encrypted handshakes, app caches, and requests made directly to an IP can all affect the result. When troubleshooting, first check whether the incoming request contains a domain or an IP. Then choose domain rules, IP rules, or routing by entry point. A rule with the right name isn't necessarily being matched.

To verify a change, clear the app's old connections, make a fresh request to a known destination, and check the destination and outbound tag in the access log. Browser connection reuse can make a new rule appear ineffective. Restarting the core may not clear the browser's own cache, either. If enabling logs produces too much output, narrow the test and turn off verbose logging promptly. Test one new rule at a time, then expand to a domain set after confirming it matches. This makes it easier to tell whether the problem is rule order, resolution, or a tag reference.

DNS Configuration: Check Resolution and Connection Paths Separately

Identify which layer is handling DNS requests

A request may involve system DNS, an app's built-in resolver, the core's built-in DNS, and DNS resolution on the proxy server. Setting the core's dns.servers doesn't mean every app will use it. The system proxy affects requests that honor proxy settings; a browser using its own encrypted DNS may resolve domains through a separate path. First find out where the domain is translated into an IP address, then decide which resolver to configure. Otherwise, you may change a layer that the request never uses.

Also distinguish the destination website's domain from the proxy server's domain. Before the proxy connection is established, the server's own domain usually needs to resolve to a usable address; that step can't depend on the same connection that hasn't started yet. If the server address is a domain, make sure the bootstrap resolution path works before configuring split DNS for destination domains. Forcing all DNS requests through the proxy can create a startup dependency loop: the core starts, but its first connection never comes up.

Configure a resolver for specific domains

This partial Xray snippet sends domains in geosite:cn to a resolver in mainland China first, while keeping a general-purpose resolver available. expectIPs checks whether returned addresses fall within expected ranges; it doesn't verify a website's identity or guarantee the best route. This setup requires the relevant rule data. The example is only useful for testing if your local network can reach those DNS addresses. Check the actual core and routing settings to determine which outbound carries DNS requests.

{
  "dns": {
    "queryStrategy": "UseIP",
    "servers": [
      {
        "address": "223.5.5.5",
        "domains": ["geosite:cn"],
        "expectIPs": ["geoip:cn"]
      },
      "1.1.1.1"
    ]
  }
}

Domain matching, expected-IP filtering, and fallback lookups all affect the result. Don't assume the server array simply means “try the second server if the first fails.” Before adding resolvers, check whether the current core supports the fallback policy fields, then use logs to verify what queries actually do. If one resolver already returns results reliably, adding more can increase delays and uncertainty. For domains that must use a specific path, set the match scope and fallback behavior explicitly instead of guessing from array order.

Choose plain DNS, DoH, and an address-family policy

Traditional DNS commonly uses UDP or TCP on a designated port. DoH carries DNS queries over HTTPS, protecting the link to the resolver, but it isn't a proxy and won't fix incorrect routing. If the DoH URL uses a domain, its own bootstrap resolution must also be considered. Enable it only if the current core supports the address format, the network can reach the endpoint, and certificate verification succeeds. Don't disable certificate verification just to clear an error; that changes the security boundary of the connection.

UseIP allows queries for both address families according to the configuration; UseIPv4 and UseIPv6 limit queries to one family. Restricting queries to IPv4 can help determine whether a problem involves the IPv6 path, but it isn't a permanent fix for every network. If the system returns IPv6 addresses while TUN only intercepts IPv4, an app may prefer a path that isn't being intercepted. Check DNS results, system routes, and outbound capabilities together instead of changing only the resolver address.

If you can connect but some domains won't load, record the system's DNS result and the core's DNS log for the same domain, then check whether the expected domain rule matched. A system lookup tool only reports the path it used; it doesn't represent the result inside a proxied request. Next, restart the test app, clear its DNS cache or wait for entries to expire, and make a new connection. Refreshing the client list doesn't clear caches at every layer, so an old address may remain in use for a while.

Save a baseline configuration that uses just one reachable resolver. After adding split DNS, test a regular domain, then the specified domain set, and finally the first connection after a restart. If only cold starts fail, check bootstrap resolution dependencies first. If failures occur only after running for a while, check caches, network changes, and resolver reachability. This layered approach is easier to diagnose than enabling DoH, FakeDNS, and complex fallback rules all at once.

TUN Mode: Check Traffic Capture and System Routes

System proxy, virtual network interface, and Android VPN: what's the difference?

A system proxy provides apps with a proxy address; only programs that honor the setting use it. TUN receives IP traffic routed to a virtual network interface, then a component converts it into proxy requests. These operate at different layers. Enabling TUN doesn't change the server protocol or guarantee that every program is captured. On desktop, start with the TUN option provided in v2rayN. Check the current client's generated configuration to see which component handles the traffic and what format it uses.

On Android, v2rayNG typically uses the system VPN service to receive app traffic. Its permission prompt and setup differ from installing a virtual network interface on desktop. Don't import a desktop TUN configuration file into the Android client. v2flyNG follows a different core path, so its features can't be inferred from v2rayNG's menus. After choosing a client, verify a regular connection first, then enable system-level traffic capture separately. This helps distinguish server configuration problems from issues at the device's traffic entry point.

Check for routing conflicts before enabling TUN

Before enabling TUN, close other network tools that are capturing the default route, and note any existing VPNs, virtual machine adapters, and enterprise network settings. When multiple components modify the default route, DNS, or firewall, behavior may depend on startup order. If desktop permissions need to be elevated, follow the client's prompt instead of launching multiple instances to work around an error. If the virtual interface fails to start, check permissions and driver logs before changing subscriptions or protocols.

Check whether the proxy server's own connection is being sent back through the virtual interface. When TUN captures most traffic, the underlying proxy connection needs a valid bypass route, which the client usually handles automatically. Manually adding system routes or changing interface bindings can break that exclusion and create a traffic loop. A common symptom is that everything disconnects when capture is enabled and recovers as soon as it's disabled. Restore automatic interface and default-route settings first, then reapply custom settings one at a time.

MethodTraffic entry pointCheck first
System proxyApps that follow the system proxy settingsWhether the app supports it and the address and port are correct
Desktop TUNSystem routes send traffic to a virtual interfaceInterface permissions, routes, DNS, and proxy-connection bypass
Android VPN serviceApp traffic covered by system authorizationVPN permission, per-app list, and background operation

Test TCP, UDP, and LAN separately

A webpage loading only proves that part of the path works. It doesn't confirm that UDP, real-time audio or video, or LAN access works. TUN can receive UDP, but the outbound protocol, server, and destination network must support it too. If a test fails, first check whether the request reached the client, then whether the outbound supports that network type. Don't hide the problem by dropping all UDP traffic; apps may fall back to another transport, or some features may stop working altogether.

LAN access also depends on private-address routing, firewall rules, and name resolution. A bypass-LAN rule usually controls where connections go; it doesn't automatically make printer discovery or multicast broadcasts work. First test basic connectivity using the device's actual private IP address, then check whether traffic capture affects its discovery protocol. Allowing LAN connections is a separate setting that opens the local proxy listener. It is not the same as letting this device access LAN devices; don't enable it casually to fix the latter.

On Android, choose explicitly whether per-app proxying means “only proxy selected apps” or “bypass selected apps.” The same app list produces opposite results depending on the mode. App updates, reinstallations, and work profiles can change which apps are visible. After changing the list, reconnect the VPN before testing. Some systems impose extra limits on background processes. If the connection drops when the screen locks, check battery and background activity settings before blaming routing rules.

Test stability when enabling and disabling capture, switching networks, and resuming from sleep. Check whether the system DNS and default route are correctly restored each time, so no unreachable resolver is left behind. If the system can't connect after the client closes, restore the system proxy and automatic DNS settings first, then check for leftover virtual-interface settings. Recording the changes before and after traffic capture helps distinguish local network-state problems from remote connection failures and makes it easier to return to a verified standard proxy setup.

FakeDNS: Maintain Domain Mappings, Not Connections to Virtual IPs

What virtual addresses are for

FakeDNS assigns a virtual IP to a queried domain and stores the domain-to-address mapping in the core. When an app later connects to that address, the proxy component uses the mapping to recover the domain, then applies routing and outbound rules. A virtual IP isn't the destination server's real address, nor is it reachable directly from an arbitrary network. FakeDNS can preserve domain information for later connections that carry only an IP, provided resolution and connection handling use compatible paths.

So adding fakedns to DNS settings alone doesn't make a complete setup. The client must send relevant queries to FakeDNS, capture connections to the virtual address range, and use an entry point that can restore the mapping. With a system proxy, an app that resolves a domain itself and connects outside the proxy may get an address the external network can't route. Confirm the traffic capture scope before enabling FakeDNS; don't use it to compensate for system routes that aren't configured correctly.

Check the address pool and sniffing support first

This partial Xray example shows how DNS settings and the address pool relate; it doesn't include TUN traffic capture. 198.18.0.0/15 is a special-purpose range reserved for benchmarking and often used as a virtual address pool; it isn't a real destination network. Enterprise networks and other traffic-capture tools may use the same range. If there's a conflict, plan the ranges rather than simply expanding the pool. Merge the inbound snippet into the inbound that actually receives the relevant traffic; creating an unused inbound won't work.

{
  "dns": {
    "servers": ["fakedns"]
  },
  "fakedns": [
    {
      "ipPool": "198.18.0.0/15",
      "poolSize": 65535
    }
  ]
}

For the Xray inbound that actually handles the traffic, sniffing can be configured as follows. destOverride uses fakedns to restore relevant domains, while routeOnly controls how sniffed results are used for routing. Check the current core and generated configuration to see whether the client creates these options automatically. If another component handles the client's TUN path, this Xray inbound snippet is not a general-purpose TUN configuration.

{
  "sniffing": {
    "enabled": true,
    "destOverride": ["http", "tls", "fakedns"],
    "routeOnly": true
  }
}

Manage caches and mapping lifetimes

Mapping lifetime is a key troubleshooting point. An app may cache a virtual IP, but after the core restarts it may no longer have the original mapping. The old connection then has only a virtual IP, with no way to recover the real domain. This can look like FakeDNS worked at first but some apps failed after the client restarted. Close the app's existing connections and clear its relevant DNS cache before resolving and connecting again. Don't save a virtual IP as a permanent server address or copy it to another device for testing.

The address-pool capacity limits how many mappings can be maintained; it isn't a concurrent connection limit or a performance score. When many different domains are visited over time, mapping replacement and app caching can combine to cause problems. Increasing capacity blindly won't fix connections that aren't being captured. First verify on a small scale that queries reach FakeDNS and connections return through the same handling path. Once the basic flow works, decide whether capacity needs adjustment based on the core documentation and device resources.

Some apps inspect DNS results, use hardcoded addresses, or make their own encrypted DNS requests. These behaviors can bypass the intended mapping flow. For an incompatible app, first try restoring real DNS while keeping the other routing settings, then compare the results. If the app works only when FakeDNS is disabled, investigate the mapping path instead of immediately changing subscriptions. If specific domains need real DNS, make sure subsequent routing can handle the real addresses so the two sets of rules don't conflict.

Test at least four cases: the first lookup, app restart, core restart, and network change. If logs keep showing virtual destination addresses without restored domains, check whether the mapping exists and whether the right inbound is handling traffic. Don't add direct-routing rules for virtual IPs. A virtual address sent directly to an external network usually can't reach its intended destination. Restore the domain mapping and traffic-capture flow instead of widening the direct-route scope.

Managing Multiple Subscriptions: Separate Sources and Update Policies

Track each source separately instead of merging everything into one list

The main challenge with multiple subscriptions isn't how many you import; it's how sources, update results, and the active server relate. Use a separate group for each source and record its purpose, how you obtain it, and whether automatic updates are allowed. Give entries remarks that reflect their actual use instead of relying on names that may change. Keep manually maintained special configurations in their own group to protect them from subscription refreshes. To compare sources, test each in its own group before choosing a primary.

A subscription may provide addresses, ports, protocols, and transport parameters, but don't assume it controls all client routing, DNS, or traffic-capture settings. The scope varies by subscription format; some provide only a server list. After importing, check what actually changed, especially the selected core and transport fields. Converting a source to another format may also drop some of its original capabilities. If parsing succeeds but connections fail, check whether all original parameters were preserved.

Avoid confusion from duplicate names, deduplication, and update overwrites

Two sources both labeled “Backup” don't necessarily connect to the same server; different names can also point to the same address. Before deduplicating, decide what counts as a duplicate. At minimum, compare protocol, address, port, identity fields, and transport settings. Deleting entries based only on address and port can remove valid configurations with different credentials or security parameters. If the deduplication method isn't clear, export a backup and work on a copy; don't clean up the only usable list directly.

Keep manual changes to subscription entries traceable. Changing a server remark temporarily is usually low-risk, but edits to SNI, transport paths, or public keys may be overwritten by the next update. For changes you need to keep, create a separate manual entry and record its source and the reason for the change. Don't turn off subscription updates just to hide a configuration conflict. That can leave you using stale addresses or service parameters and make later troubleshooting harder.

Group purposeUpdate policyWhat to keep
Primary sourceUpdate periodically after verificationActive configuration and last known-good backup
Backup sourceUpdate separately and spot-checkIndependent retrieval path and usable entries
Manual configurationsManual changesOriginal source, reason for changes, and rollback settings
Test groupImport as neededTest conditions and results without replacing the primary configuration

Handle updates, selection, and failover separately

Updating a subscription, testing latency, and selecting the active server are three separate actions. A successful update doesn't mean the client has switched servers, and list order doesn't mean automatic selection. If the client offers auto-selection, check its trigger conditions, test target, and selection scope. A reachable test target doesn't mean every service is reachable, and a successful TCP handshake doesn't mean the full request succeeds. For details on what each test measures, see Latency Tests vs. Download Speed Tests.

Schedule automatic updates outside periods when you need stable long-lived connections, and check whether an update reloads the core. On mobile devices, network changes or battery-saving mode may delay scheduled tasks, so don't treat automatic updates as precisely timed. Check the configuration and connection before important use. If multiple subscriptions all rely on the same failed connection to update, the backups may fail to refresh too. Keep an offline backup of a configuration you've already verified.

Subscription URLs often grant access and shouldn't be treated like ordinary public links. Browser history, screenshots, clipboard syncing, and exported files may all contain the full URL. When sharing a configuration, include only the fields needed for troubleshooting; don't disclose subscription URLs or connection credentials. If you suspect a URL has been exposed, change its access credentials using the source's management tools, then update the client. Renaming a local group won't invalidate the old URL or prevent other devices from using it.

Use a fixed failover procedure: confirm the current group and active server, check whether the subscription just changed, then switch to a verified backup entry. After switching successfully, keep a copy of the failed configuration and investigate it separately; don't delete the entire source right away. If two independent sources fail at the same time, first check local DNS, system time, network permissions, and traffic-capture settings. Multiple sources can reduce the impact of some failures, but they can't bypass a shared network problem on the same device.

Custom Outbounds: Manage Tags, Default Routing, and Rollback

First, find out what generates the configuration

Outbounds define how the core connects to destinations; routing decides which outbound handles each request. A graphical client usually generates the runtime configuration from the active server, routing mode, and settings. Direct edits to a temporary generated file may be overwritten at the next launch. Before making long-term customizations, check whether the client provides a custom configuration or template entry point, and export the current result for comparison. On desktop, use v2rayN's graphical options for routine settings; maintain the full configuration only when the UI can't express what you need.

Xray, V2Fly, and other network components don't share interchangeable configuration formats just because their fields look similar. The examples in this section use Xray-style JSON and can't be imported directly into every client. A custom full configuration may also bypass the client's server-list generation, so changing the selected list entry may not change the connection target. After saving, check the actual startup file, core type, and configuration-loading logs. First rule out the possibility that you edited a file the client never uses.

Validate the setup with direct and block outbounds

This partial outbound array uses freedom for direct connections and blackhole to discard matching traffic. The first entry usually becomes the default outbound when no other rule handles a request, so this example defaults to direct. It isn't a complete proxy setup. To add a real proxy outbound, preserve the correct connection parameters from a client configuration you've already verified, then reference its tag in your routing rules. Don't invent server credentials or identity details.

{
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ]
}

Keep tags short, stable, and unique within a configuration. If you rename proxy to proxy-main, update every routing rule and related setting that refers to the old tag. Don't substitute a display remark for a tag or assign the same name to different outbounds. A simple table of inbound tags, rule conditions, and destination outbounds makes it easier to check that every reference has a definition than inspecting JSON indentation alone.

Tell chaining, routing, and automatic failover apart

Adding multiple outbounds only makes multiple connection methods available; it doesn't enable automatic failover. Routing requests to different outbounds based on their destinations is split routing. Using one outbound to establish another connection is chaining. Choosing an outbound based on observed results requires a separate selection mechanism. These are different behaviors. Without explicitly configured health checks and selection logic, a failed first proxy won't switch to the second just because it's in the array. Adding duplicate outbounds won't improve availability, either.

Chaining adds dependencies: DNS, transport support, and stability on the first leg all affect the next. If one leg doesn't support the required network type, the final request still fails. Verify each outbound on its own before attempting to chain them, and check that the current core supports the relevant fields. Don't add multiple layers of chaining, complex routing, and different DNS strategies all at once. If something breaks, it'll be difficult to identify which leg failed or make sense of the logs.

Validate the final configuration with reversible changes

Validate custom configuration syntax and loading before testing real traffic. Valid JSON doesn't guarantee the current core supports every field, and successful loading doesn't guarantee that routing references are correct. If startup fails, use the log to locate the reported object instead of deleting the entire routing section. Restore the last working version, then add one outbound or one rule at a time. If the client offers a configuration test, use it. Otherwise, keep the original file and a recoverable graphical configuration before restarting.

For real-world tests, choose one destination that should go direct, one that should use the proxy, and one clearly defined test destination that should be blocked. Check logs and app results for each. Limit block rules to well-defined domains or test targets to avoid interfering with updates and DNS requests. When a connection fails, start by checking whether the inbound received the request, then inspect the matching rule, outbound tag, address resolution, and remote handshake. Don't infer a server failure from the final timeout alone. For the desktop log location, see v2rayN Main Window Guide.

Save the working configuration together with the reason for each change and the conditions used to verify it. Recording the traffic-capture method, DNS path, and outbound tags is more useful for reproducing results than simply noting “the internet works.” Remove unnecessary sensitive details before exporting, and create a redacted copy for sharing. If you later change cores or clients, verify the original baseline before migrating custom fields. For everyday connections, follow the connection and verification steps in Getting Started. Keep only complex settings that serve a clear purpose and that you can explain.