Configuration flow and troubleshooting boundaries
First separate the client interface, core configuration, and operating-system network layer. Troubleshoot each issue at the layer where it occurs instead of changing several parameter groups at once.
Build a three-layer configuration model first
The quick start page covers the core path: importing a subscription, choosing a server, enabling the system proxy, and verifying access. This guide handles the detailed work that follows, including subscription isolation, complex routing, DNS query paths, TUN capture scope, and custom outbound settings. Before changing anything, split the current configuration into three layers: the outer layer is the interface settings in v2rayN, v2rayNG, or v2flyNG; the middle layer is the runtime configuration generated by the client and passed to Xray or V2Fly; the bottom layer is the operating system’s proxy settings, routing table, virtual adapter, and name-resolution behavior. These layers affect one another, but they are not interchangeable.
For example, in v2rayN, “Set system proxy” only points applications that support system proxy settings to a local listening port; it is not a routing mode. “Bypass mainland China” is a core routing rule that decides whether a request is sent to the direct or proxy outbound after entering the core. TUN mode takes over more connections at the operating-system network layer, so even applications that ignore system proxy settings may be captured by the virtual adapter. Treating these three features as one switch commonly produces a browser that works while command-line tools fail, or traffic that still passes through the core after the system proxy is disabled.
Change only one layer at a time. Save the last known-good configuration, record the change, restart the core, review the logs, and then run a fixed test set. Include at least one domain request, one request to a literal IP address, one target that should clearly use direct, and one target that should clearly use proxy. If routing, DNS, and TUN all change together, the logs can show only the final failure, not where the first deviation occurred.
Understand the real path of a request
In a standard system-proxy setup, the application first connects to the HTTP or SOCKS inbound exposed by v2rayN. The core reads the destination, resolves the domain when necessary, and matches an outbound tag using the routing rules. For direct, the core opens the connection through the local network; for proxy, it hands the connection to the proxy outbound associated with the current server; for block, the request ends locally. TUN adds one step: the operating system sends IP packets to the virtual adapter, the core reconstructs the connection target, and only then follows the same routing and outbound process.
Routing matches the information that is visible. A SOCKS inbound can usually carry the original domain, allowing the core to match domain or geosite. Some programs resolve the domain themselves and submit only the destination IP, so the core sees an IP and domain rules may not match. Traffic sniffing can recover a domain from handshake data for some connections, but it does not work for every protocol and should not replace a correct DNS configuration. When a rule does not match, first confirm whether the target recorded in the logs is a domain or an IP.
DNS is not an isolated module either. Routing may need to resolve a destination IP, DNS queries need an outbound path, and under TUN the system query may be intercepted by the core. If every DNS request goes to one remote resolver and that resolver’s domain itself requires the proxy outbound, startup can become circular: the proxy server is not connected yet, so the resolver is unreachable too. The fix is not to keep switching servers, but to provide a directly reachable bootstrap resolver for the startup path and explicitly define which queries use direct and which use proxy.
Use logs to identify the layer instead of relying on interface status
A “Connected” status usually means only that the core process has started; it does not prove that every request reaches the correct outbound. First check that the listening port exists, then confirm that the request entered the expected inbound, inspect the routing result, and finally review outbound connection errors. If there is no test request in the logs, investigate application proxy settings, the system proxy, or TUN capture. If an inbound record exists but the rule result is unexpected, investigate target identification or rule order. If the expected outbound was selected but the connection failed, check the server configuration, network reachability, and time settings.
- Confirm whether you are changing the original subscription item, the client-generated configuration, or the system network settings.
- Before making changes, export the client configuration or record the key options so you can return to a known state.
- During testing, close other network tools that rewrite proxy settings to prevent port and routing-table conflicts.
- Repeat tests with the same targets. Compare routing matches first, then compare the final access results.
For advanced desktop configuration, use v2rayN first because its subscription groups, routing rules, DNS, and TUN controls are centralized, and its logs are easier to compare. On Android, use v2rayNG; choose v2flyNG when the V2Fly core is required. The download entry points and supported platforms are listed on the client download page. Interface labels may change, but the core path—“inbound → routing → DNS → outbound”—remains consistent. The following chapters use this path throughout.
Subscription groups and server filtering
Manage subscription sources, server entries, and the current selection separately. Filtering should change only the visible set, not damage the original subscription content.
Create groups by source instead of stacking every entry together
The first purpose of a subscription group is to identify its source. When adding a subscription, give each URL a stable note such as “Work,” “Mobile backup,” or “Test,” rather than names like “Subscription 1” or “New address” that cannot be traced later. After an update, server entries should retain their group relationship. If duplicate names, different routing behavior, or a failed source appear later, you can narrow the scope immediately instead of guessing entry by entry.
The second purpose of a group is to isolate updates. A subscription update usually rereads the remote content and adds, changes, or removes entries in that group. If you manually changed a server address, port, or transport parameter before updating, the next sync may overwrite it. Copy any long-term custom entry into a separate local configuration and note its source and purpose; do not rely on an implicit promise to “stop updating after editing.” Record the original value for temporary changes and delete the copy when testing ends.
The third purpose of a group is to control bulk actions. Before testing servers, exporting selected items, enabling entries in bulk, or deleting them, limit the operation to the current group. With multiple subscriptions, identical notes may come from different sources, and the displayed name alone cannot show whether they share a server configuration. Let the group name describe the source and the entry note describe the region, protocol, or purpose. These fields carry different information; do not pack every attribute into one excessively long name.
Filtering only narrows the visible set
Server filtering works well for subscriptions with many entries and consistent naming. Common conditions include note text, regular expressions, protocol type, and group. Start with a simple text match, confirm the result, and only then move to a regular expression. Account for case, spaces, hyphens, and character variants. For example, to keep notes containing “Backup” or “Test,” use Backup|Test; to exclude them, use the client’s exclusion condition instead of simulating all logic with an overly complex negative expression.
Filtering and deletion are different. Filtered entries remain in the subscription group but disappear from the current view or candidate list; deleted entries may return during the next update. If a category is permanently unnecessary, exclude it in the group’s filter conditions. If you only need to focus temporarily on one protocol or region, filter the view without changing the subscription. When the result is empty, clear the rules first to restore the full list, then add conditions one by one. This distinguishes an actually empty subscription from an expression that is too broad.
Keep condition:
(Backup|Test).*(VLESS|Trojan)
Exclude condition:
Expired|Maintenance|Temporary
Explanation:
Match purpose terms first, then protocol terms;
Run the exclusion condition independently instead of combining everything into one complex expression.
This example illustrates filter order; actual matches are made against the server notes supplied by the subscription.
Keep a rollback point when updating subscriptions
Before updating, confirm which group contains the current server and record the notes of the working entries. After the update, do not immediately delete old entries in bulk; first review additions, removals, and parameter changes. If the client can retain existing entries during an update, enable that temporarily for troubleshooting, then remove duplicates once the configuration is stable. Keeping old and new entries indefinitely creates selection confusion and may cause automatic selection to continue using an unmaintained configuration.
When a subscription URL cannot be read, troubleshoot by network layer. First confirm that the URL is complete and has no leading or trailing spaces. Next confirm which proxy path the update request uses: direct, the system proxy, or the current core. Then check whether the response is a subscription format the client can parse. A login page, error message, or empty response may be reduced to “parse failed” in the client. Switching servers usually will not help; fix the subscription request itself first.
If an update succeeds but produces no new entries, check the current group, filters, duplicate handling, and protocol support in that order. Some entries may be treated as duplicates because their notes match, or may not be imported because the current core does not recognize a field. v2rayNG targets Xray configuration by default, while v2flyNG targets the V2Fly core. When a subscription contains core-specific extensions, match the client to the core’s capabilities instead of deleting unknown fields by hand and continuing.
Build a consistent server-selection workflow
A server test describes performance only at a particular time, with a particular method and target; it does not replace checking protocol parameters. First remove entries with incomplete fields, unresolvable addresses, or mismatched transport settings, then run connection tests. After selecting a server, verify routing and DNS with a real application request instead of relying only on the client’s test. If several entries share a domain, DNS caching and connection reuse may affect short tests; after switching, wait for old connections to end or restart the relevant application.
Keep one verified baseline entry. After changing routing, DNS, TUN, or custom outbound settings, always test the baseline first. If it also fails, the issue is more likely local configuration. If only the new entry fails, check its protocol, port, transport, security layer, and server name. This comparison prevents local rule issues from being mistaken for subscription problems and avoids changing several variables in succession.
For subscription formats and desktop or Android import steps, see the V2Ray subscription link import guide. This chapter focuses on management after import: traceable sources, reversible updates, undoable filters, and baseline-based selection. Once all four are in place, multiple subscriptions and complex routing have a stable foundation.
Routing rules in practice
Rules are evaluated in order, and the first match determines the outbound. Put high-confidence exceptions first, category rules next, and the fallback last.
Choose the outbound tag before writing match conditions
A routing rule does not simply “allow” or “deny” traffic; it sends the request to a specified outbound. Common tags include proxy for proxy traffic, direct for direct connections, and block for blocked traffic. The actual tags generated by the client may differ, so inspect the current outbound names before copying rules. Referencing a nonexistent tag may prevent the core from starting or produce an unexpected result.
A rule can match domains, IPs, ports, inbound tags, network types, or protocol characteristics. Domain conditions suit specific sites and geosite categories; IP conditions suit LANs, private addresses, and geoip categories; inbound tags let you send different local ports or TUN traffic to different outbounds. Do not combine unrelated conditions in one rule: different fields in the same rule are generally required together, making the scope narrower than expected.
The rule list is checked in order, and the first match ends evaluation. Put precise rules before category rules, and category rules before the final fallback. For example, if a domain in geosite:cn must use proxy, create a separate proxy rule for that domain before routing geosite:cn to direct. If the order is reversed, the category rule matches first and the exception never runs.
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"domain:internal.example"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:geolocation-!cn"
],
"outboundTag": "proxy"
}
]
}
}
This is an example of a core routing structure. Outbound tags must match the client-generated configuration.
Understand the effect of domainStrategy
AsIs means the routing stage prefers the original target and does not proactively resolve a domain for IP rules. A request carrying a domain can match domain rules; only an IP target can enter IP rules directly. Its behavior is simple and suits configurations organized mainly by domain. The drawback is that when a domain matches no rule, later geoip conditions cannot take over unless the application has already resolved it to an IP.
IPIfNonMatch tries domain rules first, resolves the domain when none matches, and then tries IP rules. It suits a structure where domain categories take priority and IP geography provides the fallback, making it a common balanced choice. The lookup at the routing stage uses the core DNS configuration, so an incomplete DNS setup can look like a routing failure. If the logs show resolution errors, fix DNS before adding more domain exceptions.
IPOnDemand triggers resolution earlier when a rule may require an IP. In complex rules it can increase query volume and make requests that only needed domain matching depend on DNS results. Unless early IP resolution is specifically required, do not use it as a general switch for “rules not matching.” Choose the strategy based on the rule structure, not on which name sounds more complete.
| Strategy | Resolution timing | Suitable structure | Main consideration |
|---|---|---|---|
AsIs |
No proactive resolution during routing | Domain rules first, with an explicit fallback | Domain requests do not automatically enter geoip rules |
IPIfNonMatch |
Resolve after domain rules do not match | geosite first, geoip fallback | The core DNS must work correctly |
IPOnDemand |
Resolve when a rule may require an IP | When an early IP decision is explicitly required | Earlier queries create a longer troubleshooting path |
Organize rules into explainable layers
Divide rules into five layers. The first handles private networks and local resources, such as geoip:private and internal domains, usually through direct. The second contains precise exceptions that must override category results. The third covers protocol- or application-specific rules, such as separating browser and development-tool ports by inbound tag. The fourth contains broad categories such as geosite and geoip. The fifth is the final fallback, explicitly choosing whether unmatched requests use proxy or direct.
Keep block rules traceable. If you immediately block a broad category list, an application failure becomes difficult to distinguish from a remote problem. Start with clearly identified domains and keep the routing result in the logs. Do not block UDP, LAN discovery, time synchronization, and similar system traffic simply because it “looks unnecessary”; under TUN, these requests can affect network-state detection and application startup.
Port rules must consider both the destination port and the transport protocol. Matching only 53 may cover both TCP and UDP DNS; matching only UDP also includes other real-time traffic. To handle DNS alone, constrain the port, network, and inbound source together. If an application must always use a specific outbound, give it a dedicated inbound port or use the client’s supported process-matching capability instead of guessing its behavior with an ever-growing list of destination domains.
Handle changes after geosite and geoip updates
The classification database changes the scope of a rule. If some domains take a different path after an update, first confirm that the current core reads the data files, then confirm that the category exists, and finally check whether the exact domain moved into a new set. Do not duplicate the same rule to cover the issue; first-match behavior does not change when rules are repeated. For file roles, replacement steps, and rule troubleshooting, see how to update geoip.dat and geosite.dat.
After completing the routing configuration, export an annotated rule list. Record the order, purpose of each layer, required outbound tags, and database categories at minimum. Preset modes in the client are useful for quick selection, but once custom rules are added, use the generated configuration as the source of truth. This makes it possible to tell whether differences after a client update, core switch, or device migration come from interface presets or core fields.
DNS configuration tuning
Map the query path first, then choose resolvers, outbounds, and caching behavior. DNS results must remain consistent with later routing decisions.
Separate system DNS, core DNS, and application-level resolution
System DNS is the name-resolution entry point provided by the operating system to ordinary applications. Core DNS is the resolver module configured in Xray or V2Fly, mainly serving routing decisions, proxy-server address resolution, and intercepted DNS requests. Some browsers and applications also use their own encrypted DNS and bypass system settings. These paths can coexist, so “changing DNS” must specify which layer changed.
In ordinary system-proxy mode, when an application passes a domain to a SOCKS or HTTP proxy, the core can see the domain and process it using its own configuration. If the application first resolves the domain with system DNS and then connects to the proxy, the core may see only an IP. Under TUN, system DNS requests can be captured by the virtual adapter, but application-provided encrypted DNS may still run as ordinary HTTPS traffic. When investigating different resolution results, disable the application’s custom resolver first, establish a baseline with the system path, and restore layers one at a time.
The goal of DNS configuration is not simply to find the fastest resolver. Queries must be reachable, results must suit the current network, and routing must make consistent decisions from them. If domain rules use geosite to choose an outbound but the application resolves first and submits only an IP, geoip or fallback rules will decide instead. Either outcome can be valid, but it must match the intended design.
Assign explicit resolvers to different domains
Core DNS can use multiple servers and select among them by domain category. Internal domains should go to a resolver that knows the internal zone; ordinary direct domains can use a resolver reachable through the local network; a resolver that must be accessed through a proxy must specify its outbound or avoid a routing loop. Do not simply list every server and expect the core to choose the “best” answer automatically. Different cores and fields handle concurrent queries, fallback, and expected IPs differently.
{
"dns": {
"hosts": {
"router.internal": "192.168.1.1"
},
"servers": [
{
"address": "223.5.5.5",
"domains": [
"geosite:cn"
],
"expectIPs": [
"geoip:cn"
]
},
{
"address": "1.1.1.1",
"domains": [
"geosite:geolocation-!cn"
],
"skipFallback": true
},
"localhost"
],
"queryStrategy": "UseIP"
}
}
This example shows a categorized query structure. Configure actual addresses and outbound paths for the current network.
hosts is suitable for a small number of fixed internal names or specific overrides. It is not a replacement for a large domain list and should not store frequently changing external addresses. domains limits the domain set handled by a resolver; understand its order and matching priority alongside the core’s rules. expectIPs checks whether returned addresses fit the expected category. It can assist fallback, but an outdated classification database or geographically distributed service can make overly strict conditions reject otherwise usable results.
Choose IPv4 and IPv6 query strategies
UseIP generally permits usable IP types, with exact behavior depending on system and core support. UseIPv4 requests or retains only IPv4 results and suits networks without stable IPv6 routing. UseIPv6 uses IPv6 only, provided the local network, proxy server, and destination path all support it. Do not permanently disable IPv6 because of one failed connection; first identify whether the failure occurred at the local exit, the proxy outbound, or the destination.
A common dual-stack issue is that DNS returns an IPv6 address while the current outbound can establish only IPv4 connections. The application may wait for an IPv6 timeout before falling back to IPv4, making the first load slow. Temporarily use UseIPv4 in core DNS to verify the cause. If latency disappears, inspect the system IPv6 route and outbound support; if nothing changes, address-family selection is not the bottleneck. Conversely, forcing IPv4 can break internal resources available only over IPv6, so internal domains are better handled by separate servers and rules.
| Symptom | Check first | Check next | Avoid |
|---|---|---|---|
| Domain fails, IP connects | Whether the query reached the expected DNS | DNS outbound and returned address family | Repeatedly switching server entries |
| First connection is slow, then normal | IPv6 fallback and caching | Application connection reuse | Adding many domain exceptions |
| Unstable routing categories | Whether the core sees a domain or an IP | domainStrategy and sniffing | Reordering identical rules repeatedly |
| Internal name cannot be resolved | Whether the query was sent to internal DNS | TUN DNS capture scope | Sending internal domains to a public resolver |
Avoid DNS loops and startup dependencies
If the proxy server address is a domain, the core must resolve it during startup. If the only DNS server is reachable through a proxy outbound that has not been established, a circular dependency results. Provide a directly reachable bootstrap resolver for the server address, or configure a static mapping when that is reliable. Static mappings require manual maintenance as addresses change, so they suit controlled environments rather than dynamically fixing a service to one IP.
Another loop occurs in DNS routing rules: all port 53 traffic is sent to a dedicated DNS outbound, while that outbound creates its own port 53 requests that the same rule captures. Narrow the rule with an inbound tag, destination address, or dedicated outbound tag so the core’s upstream queries can leave the loop. Under TUN, also prevent queries from the virtual adapter from being redirected back to the same inbound.
Troubleshoot caching by clearing first and reproducing second. Clear the application cache, system DNS cache, and core cache in turn, then make one query. Without clearing caches, an old result may remain after changing the resolver and lead to a false conclusion. Once the configuration is stable, restore normal caching; disabling it completely increases query volume and makes short network fluctuations affect every connection more directly.
Finally, test four target types separately: an internal domain, a clearly direct domain, a clearly proxied domain, and the proxy server’s domain. Confirm that each query reaches the expected server and compare the routing logs with the final outbound. Healthy DNS does not mean one server answers every domain; it means each name follows an explainable path to a usable result.
v2rayN TUN mode configuration
TUN captures connections from a virtual network adapter, including those that ignore system proxy settings. Before enabling it, stabilize ordinary proxy mode, routing, and DNS.
Define the problem TUN is meant to solve
System proxy mode depends on applications actively reading the operating system’s proxy settings. Browsers and many desktop programs do, while some command-line tools, game launchers, and applications with their own network stack may not. TUN creates a virtual adapter and changes routing so more IP traffic enters the core, where rules select direct, proxy, or block. It expands capture coverage but does not fix incorrect servers, routing, or DNS automatically.
Before enabling TUN, confirm in ordinary system-proxy mode that the baseline server connects, domain resolution works, and direct and proxy rules behave as expected. Otherwise, switching to TUN adds a virtual adapter, routing table, DNS interception, and permission variables at once, greatly expanding the troubleshooting scope. Save an ordinary-proxy configuration; if TUN fails, disable it and restore system networking before verifying the basic path again.
v2rayN provides desktop clients for Windows, macOS, and Linux, but each system handles virtual adapters, route changes, and permission requests differently. The core concepts remain the same: choose a TUN inbound, select a stack type, decide whether to use auto-route and strict-route, configure DNS capture, and ensure the core has sufficient permissions. Platform entry points are available under Windows downloads, macOS downloads, and Linux downloads.
Choose the network stack and auto-route
TUN implementations commonly offer multiple network-stack options. The system stack follows native operating-system behavior more closely and has a clear compatibility path; a user-space stack may be easier to handle across platforms but can behave differently with certain protocols, fragmentation, and local networks. Without a specific requirement, start with the client’s recommended default. If UDP, LAN access, or one application behaves unusually, switch stacks for a single-variable comparison instead of changing MTU, DNS, and routing together.
Auto-route sends traffic within scope to the virtual adapter. After enabling it, check the default route, LAN routes, and exception paths for the proxy server address. The proxy server’s own connection must not re-enter the same TUN inbound or a loop will result. Clients usually add exclusions for the server address and required system networking, but when the server uses a domain and its resolved address changes, review the logs to ensure the actual address is not captured incorrectly.
Strict-route reduces paths that bypass TUN. Once enabled, LAN access, virtual-machine networks, container networks, and enterprise network clients may be affected. Complete basic validation with strict-route off, then enable it according to the required capture scope. If only LAN resources fail afterward, add direct routes for private addresses and relevant subnets, and confirm that earlier proxy rules do not match those targets.
| Setting | Purpose | Recommended starting point | Check when abnormal |
|---|---|---|---|
| Auto-route | Send system traffic to the virtual adapter | Enable it and keep the client’s default exclusions | Default route and server-address loop |
| Strict-route | Restrict alternate paths around TUN | Enable after the basics are stable | LAN, virtual-machine, and container subnets |
| MTU | Limit the packet size on the virtual interface | Use the default value | Large pages stalling, fragmentation, and UDP |
| DNS capture | Send system queries into the core | Verify it together with core DNS | Query loops and internal-name resolution |
Handle permissions, firewalls, and leftover routes
Creating a virtual adapter and changing system routes usually requires elevated privileges. If the client says TUN is enabled but the system has no corresponding interface, first check whether the permission request completed, then inspect the core startup log. Do not keep toggling the switch; a failed start may leave a process or partial routes behind. Stop the core, exit the client, confirm the virtual interface and related process state, and then start again.
A firewall may control access by program path, interface type, or network profile. After a client update or a switch between desktop editions, the executable path may change and old rules may no longer match. When system proxy works but TUN carries no traffic, check whether the core process is allowed through the new virtual interface. When some applications work and others fail immediately, check whether the application is bound to a physical interface or uses a network method unsupported by the current stack.
After an abnormal exit, the system may temporarily retain DNS or route settings. Close TUN normally first, exit the client, and restore automatic DNS and the default route. Reset system networking only after confirming that the client process has stopped. Deleting the virtual adapter while the core is running leaves the client holding an invalid interface and produces more secondary errors in the logs.
Narrow TUN failures by symptom
If all networking stops immediately after enabling TUN, check the default route, whether the core is listening successfully, and whether the proxy server was captured in a loop. If domains fail while literal IPs work, focus on DNS capture and the upstream query outbound. If small web resources work but large ones stall, test whether the MTU is too high without changing other settings. If only UDP fails, inspect the server protocol, TUN stack, and routing rules for UDP support; do not change DNS first.
If networking remains abnormal after TUN is disabled, confirm that the virtual adapter disappeared, system DNS was restored, and the default route points to the physical network. Restarting the client core is not the same as restoring operating-system settings; use the client’s stop or restore operation first. After recovery, make a basic network request without the client, then enable ordinary proxy mode again.
Configure process rules, strict-route, and FakeDNS only after TUN is stable. For every new feature, repeat five tests: a domain request, an IP request, a direct target, a proxy target, and a LAN resource. TUN expands capture coverage; it is not meant to force all traffic through one outbound. Routing still determines the final path, so direct subnets, DNS outbounds, and server-loop exceptions must be explicit.
FakeDNS: how it works and where it stops
FakeDNS uses temporary mappings to preserve domain information for connections that carry only a destination IP under TUN. It must be configured together with DNS capture, an address pool, and sniffing.
Understand “returning a fake address while preserving the real domain”
When an application queries a domain, FakeDNS does not immediately return the real IP. It assigns a temporary address from a dedicated pool and stores a mapping between that address and the original domain. The application then connects to the temporary address. After TUN captures the connection, the core restores the original domain from the mapping and performs domain routing and the real remote connection. Even when the application submits only IP packets, the core can therefore use geosite or exact-domain rules to choose the outbound.
A temporary address is meaningful only within the local mapping scope and should never be sent to the LAN or the real outside network. If TUN does not capture the connection and the routing table sends it to the physical adapter, the application fails directly. FakeDNS must therefore be enabled together with DNS capture and TUN routing. Adding a FakeDNS server to DNS alone, without sending connections for its returned addresses into the core, produces the classic result: resolution succeeds but every connection fails.
FakeDNS mainly addresses lost domain information. It does not improve server connectivity and does not replace upstream real resolution. After restoring the domain, the core still needs to resolve the real target according to the outbound path or pass the domain to the remote side. An unreachable upstream DNS, incorrect routing tag, or server that cannot connect to the target is not repaired by FakeDNS.
Plan the address pool to avoid real-network overlap
Use a dedicated reserved range that does not overlap the current LAN, enterprise, virtual-machine, or container networks. If temporary addresses overlap a real internal subnet, an internal resource may be mistaken for a FakeDNS mapping, or an external domain’s temporary connection may be sent into the real LAN. Before enabling it, inspect the system routing table, record ranges used by the physical network, VPNs, virtual machines, and containers, and choose a non-overlapping range.
The pool size determines how many mappings can exist at once. Ordinary desktop use does not require an unnecessarily large range; a larger range increases the chance of overlapping an existing network. Mappings have a lifetime, so an application’s cached temporary address must remain recognizable while the mapping is valid. If the application keeps a DNS result after the core restarts and the mapping disappears, old connections may briefly fail. Clear the application DNS cache and query again instead of writing the old temporary address into hosts.
{
"dns": {
"servers": [
{
"address": "fakedns",
"domains": [
"geosite:geolocation-!cn"
]
},
"localhost"
],
"fakedns": [
{
"ipPool": "198.18.0.0/15",
"poolSize": 65535
}
]
}
}
The example range is for baseline illustration. Before enabling it, confirm that the same range is not used by the local system or network.
Decide which domains enter FakeDNS
Do not switch every query to FakeDNS at once. Keep internal domains, LAN device names, and zones that must be answered by local DNS on real resolution. Start with external domains that need domain-based routing and will be captured by TUN; handle other queries with their intended resolvers. The clearer the scope, the easier it is to tell whether a failure comes from the mapping, real resolution, or routing.
Some applications compare DNS results, establish direct UDP sessions, or pass addresses to devices outside the system. These workflows may not suit temporary addresses. If an application works under ordinary TUN but fails after FakeDNS is enabled, first give its domains a real-resolution exception instead of disabling FakeDNS globally. Once the exception works, decide whether the application’s domain set needs to expand.
FakeDNS and traffic sniffing can work together, but they have different roles. FakeDNS creates mappings during queries for intercepted DNS requests; sniffing tries to recover a domain from connection content when no mapping exists. When both are enabled, inspect the logs to see the source of the recovered target. If the domain or rule result is wrong, disable one feature at a time so you can identify which path supplied the final domain.
| Scenario | FakeDNS recommendation | Reason |
|---|---|---|
| Precise domain routing is needed under TUN | Enable by category | Preserve the original domain before application resolution |
| LAN devices and internal domains | Keep real resolution | They depend on local DNS and real internal addresses |
| Ordinary system proxy with the domain visible to the core | Usually unnecessary | The proxy request already carries the original domain |
| Application uses its own encrypted DNS | Standardize the query path first | The query may bypass the FakeDNS capture entry point |
Troubleshoot failures along the mapping path
First confirm that the application’s query enters core DNS. If it is not captured, the result is an ordinary real IP and no FakeDNS mapping is created. Second, confirm that the returned address belongs to the configured pool. Third, make a connection and check whether TUN captures that temporary address. Fourth, confirm that the core restores the domain from the mapping. Fifth, check which routing rule matches the restored domain. Verifying these five steps in order identifies the exact break point.
If a temporary address is returned but there is no connection log, the issue is system routing or TUN capture. If a connection is logged but the domain cannot be restored, check whether the mapping disappeared after a core restart and whether the application is using a cached old address. If the domain is restored correctly but the wrong outbound matches, return to routing rule order. If the correct outbound matches but the connection still fails, check real DNS and outbound connectivity rather than changing FakeDNS again.
After configuration, test the first query, a repeated query, an old cached result after a core restart, and a LAN name separately. The first and repeated requests test mapping reuse, the restart test checks application-cache recovery, and the LAN test verifies real-resolution exceptions. A stable FakeDNS setup has explainable domain routing, unaffected internal resources, and recovery after a restart through a fresh query; it does not turn every DNS result into a temporary address.
Multi-subscription management and configuration migration
The key to multiple subscriptions is source isolation, update boundaries, and selection rules. Do not hide source differences inside one long merged list.
Give every subscription a defined role
Before adding a second subscription, state what problem it solves. Divide sources by work environment, device purpose, protocol capability, or backup role, but do not add another source merely because it has more entries. Each subscription should have a unique note, a clear update method, and independent filters. If two sources contain many identically named entries, add a short group marker to the name so the source is immediately visible in logs and the current-server field.
Use the primary subscription for daily selection, the backup only when the primary source fails or a specific environment requires it, and the test subscription outside automatic selection. Once these roles are written in the group notes, bulk updates and cleanup have a basis. If every subscription stays enabled and is displayed together, the chance of selecting an old, duplicate, or test entry keeps increasing, and it becomes impossible to tell which source caused a parameter change.
Different subscriptions may use different protocol fields and core extensions. Successful import does not mean the current core can run them completely. See Xray and V2Fly core differences. v2rayN can handle primary configuration management on desktop; on Android, choose v2rayNG or v2flyNG according to the required core. When migrating between clients, move standard share links or supported subscription formats instead of assuming private client settings are interchangeable.
Plan update order and failure recovery
For bulk updates, use the order “backup → test → primary.” Updating non-primary groups first can reveal subscription-format changes, broken filters, or duplicate-handling issues early. Once the import structure is sound, update the primary group. Keep the currently connected entry unchanged during the update, inspect the new list, and switch only afterward so updating and connection changes do not happen at the same time.
A failed subscription update is not a reason to delete and recreate the group immediately. Record the returned error, confirm the request path and URL, and try updating it alone. Rebuilding can lose group filters, update policies, and local notes, while also breaking the relationship between old and new entries. If rebuilding is necessary, export the group settings or record the key fields first. Give the new group a temporary name and replace the old one only after verification.
Check four things after an update: whether the overall entry structure is reasonable, whether the current entry still exists, whether filtering leaves selectable items, and whether the current core recognizes the protocol fields. Do not rely on a fixed count because subscription content changes. Compare the structure instead of tracking a number that will soon be outdated. If the list suddenly becomes empty, disable filtering first; if entries exist but none starts, check core compatibility and shared-field changes.
Handle duplicate entries and local copies
Do not judge duplicates by note alone. The same name may represent different addresses or protocols, while different names may point to the same server. Before cleanup, compare the address, port, protocol, transport, security settings, and server name at minimum. A client’s automatic deduplication may cover only some fields, leaving functionally identical entries. Conversely, deleting by name can remove configurations with different purposes.
When a subscription entry needs modification, copy it to a local entry and add “Local test” plus the source group name to its note. The copy is not overwritten by subscription updates and can be used to compare transport parameters, routing policies, or core differences. After testing, apply the valid change to a maintainable source or keep one clearly documented local entry. Do not accumulate untraceable copies; after several updates they will drift from the original configuration.
Local routing, DNS, and TUN settings usually belong to the client level and should not be copied into every server entry. Separating server connection parameters from local network policy prevents subscription switching from resetting routing logic and makes it easier to identify whether a problem is server-side or local. Create a specific custom outbound chain only when a server truly requires one.
| Object | Suggested name | Update method | Cleanup condition |
|---|---|---|---|
| Primary subscription | Purpose plus source | Update after checking other groups | Delete after confirming the new group can replace it |
| Backup subscription | State the backup scope | Update separately on a schedule | Source has failed and a replacement exists |
| Test subscription | State the test purpose | Update manually | Archive or delete immediately after testing |
| Local copy | Source plus modification | Not overwritten by subscription updates | Change is complete or traceability is lost |
Migrate only explainable configuration
Before migrating, list the subscription URLs, group notes, filter expressions, current server, routing rules, DNS settings, and TUN options. Import subscriptions on the new device and verify basic connectivity first, then migrate filters and routing, and finally DNS, TUN, and FakeDNS. Do not overwrite a different system with the entire generated configuration because inbound addresses, virtual adapters, file paths, and permission requirements may differ.
Use the same baseline server and target set for the first post-migration tests. If the server connects but routing differs, compare rule order and classification databases. If domain behavior differs, compare system DNS, core DNS, and application settings. If only TUN fails, check permissions, routes, and the firewall on the new system. Layered migration takes more steps, but every step has a clear rollback point.
After organizing multiple subscriptions, keep a written configuration note describing each group’s role, filter meaning, and migration order. It does not need sensitive server fields; describe the structure only. This makes recovery possible after interface changes or reinstallation without relying on memory of the old layout.
Custom outbound settings and chained routing
Custom outbounds clearly separate proxy, direct, block, and special paths. Tags must be unique, and every reference must resolve.
Start with the smallest outbound set
A maintainable configuration should contain at least a primary proxy outbound, a direct outbound, and a block outbound. The primary proxy carries the current server connection, direct lets the core connect through the local network, and block terminates requests that clearly should not proceed. Make these three work before adding backup proxies, interface-specific direct paths, or chained outbounds. The more outbounds there are, the more complex routing tags, DNS paths, and log interpretation become.
Every outbound must have a unique, stable tag. A tag connects routing rules, DNS queries, and other outbound references; it is more than a display name. Use lowercase English and hyphens, such as proxy-main, proxy-backup, and direct-work. After changing a tag, search every configuration reference; missing one can prevent startup or send traffic into the fallback.
The proxy outbound generated automatically from the current server may change when the server is switched. If custom rules reference a logical tag that the client is expected to preserve, confirm that it still exists after switching. If they reference a manually created outbound, save that outbound independently. Do not lock the current server by copying the entire generated configuration, or subscription switching and updates will stop working.
{
"outbounds": [
{
"tag": "proxy-main",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "server.example",
"port": 443,
"users": [
{
"id": "00000000-0000-4000-8000-000000000000",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "server.example"
}
}
},
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
]
}
The addresses and identifiers in this example illustrate structure only; actual connection parameters must come from a valid configuration.
Give the direct outbound a clear boundary
direct does not mean traffic bypasses the core. It means the request enters the core and the freedom outbound opens the connection through the local network. It is still affected by core DNS, address-family policy, and outbound binding. LANs, internal domains, and clearly direct categories usually point to direct, but rule order must be correct. If TUN captures direct traffic, also prevent the outbound connection from being routed back into TUN by the system.
On a multi-interface system, a specific direct outbound can use a designated interface or source address so work and ordinary networks remain separate. Confirm that the interface name is stable and that the target subnet is reachable through it before configuring the binding. Sleep, network changes, or interface recreation can invalidate the name. If the default direct works but a custom direct fails, remove the binding to restore the baseline, then inspect the interface and source address instead of changing destination routes.
A block outbound should receive only explicitly matched traffic. A block match usually fails locally immediately, unlike a remote timeout. If the logs show a request entering block, stop checking the server. For easier troubleshooting, keep block rules together and document their purpose instead of scattering them across presets and custom lists.
Use proxy chains carefully
A chained outbound lets one proxy outbound establish its connection through another outbound. This suits networks with a clear topology but adds one or more connection layers. Every layer involves server resolution, routing, transport, and error handling. Verify each outbound independently before creating references. When the chain fails, inspect from the outermost connection inward and confirm which layer actually received the request.
Outbound references must not form loops. If proxy-a uses proxy-b while proxy-b uses proxy-a, neither can establish a base connection. A subtler loop occurs in routing: proxy-b’s server address is sent to proxy-a by a rule, while proxy-a itself depends on proxy-b. Give server addresses in the chain high-priority rules and explicitly decide whether they use direct or a preceding outbound.
Chained configurations also require a DNS plan. Decide in advance which layer resolves each server domain, which outbound carries the query, and whether the result is captured by TUN. The safest approach is to establish the first layer with an entry server that can be resolved directly, then send later connections through the established outbound. Do not make the lowest layer depend on the highest layer’s DNS path.
| Outbound type | Typical tag | Routing purpose | Key checks |
|---|---|---|---|
| Primary proxy | proxy-main |
Carry default proxy traffic | Server parameters, transport, and security layer |
| Direct connection | direct |
LAN and explicitly direct targets | Interface binding, DNS, and TUN loops |
| Block | block |
Terminate requests matched by explicit rules | Rule scope and match order |
| Backup proxy | proxy-backup |
Specific applications or manual switching | Tag references and independent usability |
Verify the complete configuration through its tags
After completing custom outbounds, list every tag and its references. Every outbound used by a routing rule must exist; every chain reference must point to a preceding outbound that can be established independently; a dedicated DNS outbound must not depend on itself; and the TUN exclusion path must cover the proxy-server connection. Then check for outbounds that are never referenced. An unused item is not always wrong, but it often indicates leftover configuration or a rule that was never created.
- Use the primary proxy outbound to test a clearly proxied domain and confirm the tag in the logs.
- Use direct to test a LAN target and a clearly direct target, confirming that neither returns to the TUN inbound.
- Use one temporary precise rule to test the backup outbound, then delete the temporary rule.
- Trigger a clearly blocked target and confirm that the logs show a local block match.
- Test again after restarting the core to rule out a false-positive state maintained only by old connections or caches.
When the configuration will not start, validate the JSON structure first, then check duplicate tags, unknown outbound references, and required protocol fields. If it starts but follows the wrong path, inspect the first routing match. If the path is correct but the connection fails, inspect the target outbound itself. Do not handle startup, routing, and connection errors in the same round of changes.
At this point, subscriptions, filtering, routing, DNS, TUN, FakeDNS, and outbounds form a complete loop. When adding rules, follow the request from its entry point through each layer instead of inferring the entire configuration from the final error. To rebuild the basics, return to the user guide and follow the quick path. To change clients or desktop versions, open the V2Ray client download page. Keep a structural note and a working baseline, and change only one variable next time.