V2RAY / CONFIGURATION REFERENCE

Advanced V2Ray Configuration Guide

Break down settings by subscription, rules, resolution, and traffic capture. Identify which configuration layer owns each setting, make changes, then use logs to verify the connection path.

For your first subscription import, server selection, and connection, follow the Quick Start. This page is a reference for when you already have a working connection: v2rayN is the recommended desktop client; use v2rayNG on Android, or choose v2flyNG based on the core you need. Find installers on the client downloads page. Client management settings are not interchangeable with core JSON configuration.

Subscription Groups & Server Filtering

Manage subscription URLs separately from connection settings

In v2rayN, open Subscription Group Settings, create a separate group, then enter the subscription URL. The group stores the update source, notes, and filter conditions; each server entry stores the protocol settings imported from that source. Editing a group note does not change remote connection details, and updating a subscription does not switch the active server. After an update, check which entry is selected in the main window.

Name groups by purpose and source, such as “Daily use” or “Compatibility testing.” Never put subscription URLs in notes, screenshots, or shared documents. URL paths and query parameters may grant access. When troubleshooting, record only the URL type, response status, and error text; redact the actual URL. Preserve its original encoding when copying it—do not remove parameters that merely look redundant.

For the first update, turn off filtering and confirm that the server list loads. Then add filters one at a time. Distinguish an empty response from a response whose entries were filtered out. For an empty response, check whether the subscription is valid, the network is reachable, and the response format is supported. If entries were filtered out, check the filter expression. Repeatedly refreshing will not fix an invalid filter and may obscure the actual response.

Narrow the filter by field and match type

Before filtering servers, check the setting’s description: does it match server remarks, protocol type, or another field? Does it use literal text, substring matching, or regular expressions? Do not assume different clients behave alike. If the field explicitly supports regex, the expression below matches remarks containing “test” or “backup.” It defines a match condition; whether matching entries are kept depends on how the filter works.

(test|backup)

Avoid starting with a complex combination of exclusions. Test against one remark that should match, another that should not, and then an empty remark. Parentheses, pipes, and periods have special meaning in regular expressions; escape a period with a backslash to match it literally. Check how the current field handles case rather than inferring it from the letters shown in the interface.

If subscription sources use different naming conventions, set filters for each group instead of putting every name into one expression. A source may change its remarks and suddenly cause an existing filter to hide every entry. Before updating, note a name pattern that should remain; after the update, check that it is still present. A change in list size alone does not indicate a service problem—the source may have changed its contents.

Understand update overwrites and connection-setting differences

Subscription entries are generally regenerated from remote data. If you need to keep transport settings customized, first check whether the client can save a separate copy or convert an entry to a manual one. Put any copy in a separate group and note that it will no longer inherit subscription updates. Do not assume edits to a subscription entry will survive the next refresh. Perform a controlled update and check which fields are overwritten.

If import succeeds but the connection fails, check the protocol, server address, port, transport, and TLS-related fields. A successful import only means the client can parse the format; it does not mean the current core supports every feature. v2rayNG and v2flyNG use different core families, so similar-looking interfaces do not make their configurations interchangeable. Confirm the protocol requirements before choosing a client.

If a subscription update fails, keep the configuration that still works; do not immediately clear every group. Check the URL, system time, certificate errors, and whether updates are routed through the proxy. See How to troubleshoot failed v2rayN subscription updates for detailed steps. Fix the source first, then restore filtering so you do not change the URL and filter logic at the same time.

Finish with a minimal test: update one group, select an entry with a known purpose, start the core, and check the logs for configuration parse errors. Enable automatic updates only after the test passes. This separates subscription format, filtering, and connection settings so a bulk change does not wipe out your working baseline.

Routing Rules in Practice

Arrange rules by match order

First confirm that the request reaches the client; then troubleshoot routing. The system proxy, an app’s proxy settings, or a TUN inbound receives requests. Routing only handles connections already received by the core. An app that does not use the system proxy will not be captured just because you added a domain rule. Before testing a rule, use an app explicitly configured to use the proxy to rule out traffic-capture issues.

In v2rayN, open Routing Settings and review the enabled presets and rule order. Rules commonly match from top to bottom, with the first match determining the outbound. Put narrow exceptions before broad categories. For example, if a domain must use the proxy, do not place a direct rule that covers it above the proxy rule. A rule cannot take effect if an earlier rule already matches.

Within a rule, conditions on different fields usually all need to match; within a domain list, any listed domain may match. Do not express “domain OR port” as a single rule that requires both a domain and a port. Split independent conditions into separate rules and check each match. Save and reload after changes; existing connections may continue using their previous route.

Distinguish domain matching from IP matching

The following fields illustrate routing configuration for Xray and commonly used V2Ray setups. Before merging them into an existing routing object, confirm that the outbound tags and rule resources exist. This example handles an ad category, then local domains, then private IP addresses. block and direct are just tags; the actual configuration must define corresponding outbounds.

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "domain": ["geosite:category-ads-all"],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "domain": ["domain:localhost"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      }
    ]
  }
}

Use domain: to match a domain and its subdomains, full: for an exact domain, and regexp: for regular-expression matching. Prefer clear, purpose-built match types and use regex only when a more complex pattern is genuinely needed. Do not confuse substring matches with domain boundaries: unrelated targets with similar names could match and be routed incorrectly without an obvious error.

geosite: and geoip: depend on the required data files being available at runtime, and the category names must exist. If the logs say a category cannot be loaded, check the resources and names rather than deleting all rules. Client-generated configurations may use a different resource mechanism; do not mix rule-set paths from incompatible formats.

Domain strategyHow it matchesWhat to check
AsIsKeep the original target unchanged; do not resolve the domain for routingWhether domain rules provide sufficient coverage
IPIfNonMatchIf no domain rule matches, resolve the domain and try IP rulesResolved addresses and IP rule order
IPOnDemandResolve as needed when matching reaches an IP ruleWhether an earlier IP rule changes the expected route

Check the default route and sniffing scope

Connections that match no rule still need a default route. Native configurations usually use a default outbound, and clients may generate additional fallback rules. Do not rely on whether the rule editor appears to end with a blank entry; inspect the actual runtime configuration. Adding custom outbounds can change their order and affect unmatched requests. An explicit fallback rule is usually easier to understand and maintain.

Enable traffic sniffing to recover domain information from supported traffic, but do not treat it as a universal domain-recovery mechanism. Whether sniffing changes the target address also depends on its options. If an app connects directly to an IP, uses an unrecognized encrypted handshake, or reuses an existing connection, the logs may still show an IP address. Do not broaden sniffing indiscriminately just to make one domain rule match.

Test one target at a time and check the target name, matched tag, and failure stage. If the expected rule does not match, temporarily move it higher to confirm that the rule works, then restore the normal order. If it matches but the connection fails, investigate the outbound and DNS instead of changing the match conditions. A correct rule match and network reachability are separate findings.

“Global proxy” can mean different things: the system proxy is an app connection method, while a global routing preset affects outbound selection inside the core. Switching to global mode does not guarantee that every program uses the proxy. For a refresher on terminology, see the glossary. If an app’s traffic is not being captured, continue to the TUN section.

DNS Configuration

Map the actual resolution path first

Check DNS at the application, operating system, client, and remote-outbound layers. A browser may use its own Secure DNS; the system may use a local resolver; the core may keep a separate cache; and the proxy server may resolve the final destination. Changing “DNS settings” affects only queries handled by that configuration. Do not assume every app will start using the new server immediately.

First confirm whether the app sends a domain or an IP address to the proxy. With a proxy method that supports remote resolution, the app can pass the domain to the proxy. If the app resolves it first and sends an IP to the client, domain-based routing may no longer have the original name. Check the app’s proxy settings or traffic-capture method; adding a DNS rule alone will not restore all the missing context.

Distinguish two key lookups: resolving the proxy server’s own address and resolving the destination. The first happens before the proxy connection is established, so it needs an independently available route. If the only bootstrap resolver is accessible only after the proxy is up, startup can deadlock. If an encrypted DNS service is configured by domain name, also consider how that name is resolved initially.

Choose resolvers by purpose

The following simplified built-in DNS snippet is for V2Fly or Xray configurations that support these fields. It uses a public resolver for general queries and delegates local domains to the system resolver. The example illustrates domain conditions and query strategy; public resolvers are not reachable on every network. Replace them as needed for your network and check whether the client overwrites this section.

{
  "dns": {
    "queryStrategy": "UseIP",
    "servers": [
      "1.1.1.1",
      {
        "address": "localhost",
        "domains": ["domain:localhost"]
      }
    ]
  }
}

Intranet services often rely on private records in the local DNS server. Sending every query to a public resolver may make those records unavailable or return addresses that do not work on the current network. Keep a clear local resolution path for corporate domains, router names, and self-hosted services. Do not treat every single-label name as a public domain, or disable all DNS routing to fix one internal name.

The resolver’s transport and the actual query route are separate concerns. Encrypted DNS protects the relevant transport link, but whether it goes through the proxy depends on the core, outbound rules, and how the client generates its configuration. Some local resolution modes bypass normal routing. Check the runtime configuration and connection logs to confirm behavior; an encrypted protocol in the server address does not tell you which path the query takes.

Conditions such as “expected IP” check whether a response falls within the rule’s expected range; they are not a general speed setting. If enabled and a valid response is rejected, fallback queries may make troubleshooting harder. First confirm that basic resolution works, then add result constraints. Keep a test domain and its expected address range as a reference for every added condition.

Test address families and caches separately

On networks that support both IPv4 and IPv6, check resolution and connectivity for each separately. Getting an IPv6 address does not mean the current outbound has a working IPv6 route. If the logs show an address being selected followed by a connection failure, check the system route and outbound support before changing query strategy. Removing all IPv6 settings may temporarily change the symptom, but does not prove the DNS service was at fault.

After changing resolvers, the browser, operating system, and core may each retain cached results. Close existing connections, restart the test app, and clear the relevant cache as needed. Do not change the server and query strategy at the same time, or you will not know what caused the result. System lookup tools test the system resolution path, not necessarily the core’s built-in DNS, so different results from a browser do not automatically mean the configuration failed.

Keep one simple resolution path as a baseline during troubleshooting. Disable complex fallback and result filtering first, and confirm that a basic query completes. Then restore domain categories, address-family preferences, and encrypted transport one at a time. If local names work but external names fail, check whether the external resolver is reachable. If the query completes but the destination is unreachable, return to the routing section and check the outbound rather than adding more resolvers.

Finally, consider the privacy implications of DNS logs. Debug logs may contain full domain names and can become a detailed record of browsing activity if retained. Restore the normal log level after testing, and redact internal names and subscription details before sharing errors. The goal of DNS tuning is a clear, understandable query path—not the largest possible list of upstream servers.

TUN Mode

Distinguish the system proxy from virtual-adapter traffic capture

The system proxy affects only apps that honor its settings. TUN mode captures system traffic through a virtual network interface and passes it to a user-space network stack or forwarding component. It can cover more apps, but also involves system routes, interface permissions, and DNS capture, so its impact is broader than a regular proxy. Before enabling it, confirm that the basic connection works in system proxy mode.

v2rayN’s TUN Mode Settings belong to the client management layer; they are not necessarily the same as a native TUN object in V2Fly or Xray configuration. Check the client’s runtime information to see which component creates the interface and generates the configuration. TUN inbound formats differ between cores. Pasting fields from another core into V2Ray JSON will not automatically convert them.

Save the working settings first, quit other tools that are capturing system routes, then grant the permissions requested by the client. For the first test, verify basic traffic capture without adding FakeDNS, custom subnets, or complex process rules. If permissions are insufficient, fix authorization or the startup method; repeatedly toggling the setting will not make a virtual interface appear. Avoid running with elevated privileges unless necessary.

Check routes, exclusions, and platform differences

Confirm how the default route is captured and preserve the correct route for connections to the proxy server itself. If those connections re-enter the same TUN interface, a routing loop can cause repeated connection attempts or timeouts. The client may prevent loops through interface binding, route exclusions, or another mechanism. Understand what is already in place before changing custom routes, and do not remove exclusions just because they look unnecessary.

To reach local devices, check that private addresses go direct and that the system still has routes to local subnets. A core-level direct rule selects an outbound for traffic it has received; the system route determines where the traffic goes first. Both must be correct. Test printers, network storage, and remote management separately; accessing one website in a browser does not prove that the LAN still works.

PlatformWhere to checkCommon limitations
WindowsNetwork adapters, routing table, client permission promptsSecurity software or another virtual adapter may interfere with traffic capture
macOSSystem network settings, permission prompts, runtime logsCreating interfaces and changing routes requires appropriate permissions
LinuxTUN device, routing rules, service permissionsDesktop sessions and background services may have different permission contexts
AndroidVPN permission, per-app proxying, background restrictionsClients generally capture traffic through the system VPN interface

On Android, v2rayNG and v2flyNG use system VPN permissions; this is not the same as managing a virtual adapter on a desktop client. Check the per-app proxy list and make sure the test app is included. With “proxy selected apps only,” newly installed apps may not be added automatically. In exclusion mode, check that you have not excluded the browser or background service you are testing.

Corporate network tools, container networks, and virtual machine software may maintain their own routes. If an address becomes unreachable after traffic capture is enabled, compare the destination subnet and selected interface before and after, then decide whether to add an exclusion. Do not route every private subnet through the proxy, or disable all traffic capture to fix one container address. Clear rules make the impact easier to understand when restoring the network.

Troubleshoot UDP, MTU, and recovery on exit

A web page loading only proves that some TCP paths work; it does not confirm UDP. Real-time communications, some DNS queries, and other UDP apps also depend on outbound support, remote support, and the local firewall. For an app-specific failure, first check which transport it uses and review the relevant logs. Do not assume every issue is caused by a failed virtual interface.

If small requests work but large responses stall, path MTU can be one troubleshooting branch; do not copy a fixed value from someone else. Rule out DNS, handshake, and outbound errors first. Then make a small adjustment within the range supported by the client, changing nothing else. Reconnect after each change and check whether the behavior is consistent. Restore the default if there is no supporting evidence, to avoid introducing performance problems.

When turning off TUN, use the client’s normal shutdown procedure first, then check that the system proxy and DNS have been restored. After an unexpected exit, do not immediately delete every network interface. Restart the client to complete cleanup, and restore settings through the system network controls if needed. For macOS authorization and network permission issues, see macOS installation and permissions. Check battery policies separately for background issues on mobile devices.

FakeDNS

Understand virtual addresses and domain mapping

FakeDNS does not return the destination’s real address. Instead, it assigns a virtual address from a dedicated pool and stores the domain-to-address mapping. When the app connects to that address, the traffic-capture component uses the mapping to recover the original domain before routing and outbound handling. FakeDNS helps identify domains in traffic that uses IP addresses; it is not a public resolver that replaces the entire DNS chain.

FakeDNS works only when the loop is complete: queries reach FakeDNS, the returned virtual addresses are captured by the same traffic-capture chain, the mappings are still available, and the inbound restores the correct domain. If any part is missing, the result may be “DNS resolved, but nothing loads.” Verify regular DNS and TUN first, then add FakeDNS. This avoids layering address mapping onto a traffic-capture path that is not yet stable.

Do not route virtual addresses directly to the real network. They do not identify the destination server and usually cannot be reached over a normal network. If logs repeatedly show attempts to connect to an address in the pool, check mapping recovery and traffic-capture scope rather than looking for a proxy server that can reach it. Domain rules and remote resolution need the original domain as input.

Align core support with inbound configuration

The following shows the FakeDNS settings used by a compatible Xray configuration: the address pool, DNS server, and sniffing settings for the target inbound. Merge them into the correct locations in the same runtime configuration; they are not three top-level objects to append arbitrarily. If the client already generates these sections, use its corresponding settings to avoid duplicate declarations or overwriting required options.

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

The second snippet is a sniffing object inside an inbound; it must not replace the entire inbound configuration. If the inbound also needs HTTP or TLS sniffing, merge the lists according to the core’s documentation rather than mechanically deleting the existing options. Virtual-address and sniffing implementations differ between cores. Before using this in v2flyNG, confirm that the selected core and client support it.

The example address pool is intended for virtual use, but check whether your device or local network already uses it. Test environments, other proxy components, and network diagnostic tools may use the same range. Overlapping addresses make routing ambiguous. Do not pick a seemingly unused public range at random. If the client allows changes, follow the implementation’s address-pool requirements and check route exclusions as well.

Pool capacity determines how many mappings can be retained; it does not determine the number of reachable servers or connection speed. A small pool may evict old mappings sooner when many domains are in use. Increasing it arbitrarily may consume more resources. Start with the implementation’s recommended default and adjust only if logs and a reproducible test point to mapping eviction. One slow-loading app is not proof that the pool is too small.

Handle caching and apps that bypass the proxy

After enabling or disabling FakeDNS, apps and the system may continue using cached results. If an app still has a virtual address after its mapping was lost on restart, failures may be intermittent. When testing a change, close the relevant app connections, clear the appropriate DNS cache, and make a fresh request. Restarting only the core while the browser reuses an old address or connection mixes old and new state.

An app’s own encrypted DNS may bypass the expected query path; a fixed-address connection does not involve a domain lookup at all. Neither flow automatically gets a FakeDNS mapping. Identify the app’s actual behavior, then decide whether to change its DNS, proxy method, or traffic-capture scope. Other apps working does not mean the problem app uses the same resolution path.

Keep regular DNS available for local names and apps that depend on real addresses. Some services pass a resolved address to another process that is not captured; that process may not be able to use a virtual address. For these cases, set an explicit resolution exception for the relevant name rather than exposing the virtual address range more broadly. Consider the app’s architecture when diagnosing address handoffs between processes.

To roll back, restore regular resolution, disable virtual mapping, clear stale caches, and reconnect—in that order. If the app still connects to a virtual address, address the cache first rather than changing server settings. FakeDNS is useful when preserving domain information in IP-based traffic is necessary. If a regular domain-based inbound meets your needs, there is no reason to enable it just to add complexity.

Managing Multiple Subscriptions

Use groups to define clear update boundaries

Create separate subscription groups for different sources, then add notes and filters based on purpose. You can also separate groups by purpose when they share a source, but watch for duplicate updates and entries. Groups do not combine connections, and adding another subscription does not automatically improve the active connection. What matters is the selected server, routing rules, and outbound configuration.

Keep “source identity,” “display name,” and “connection settings” distinct. Two entries with the same remark may point to different servers; entries with different remarks may be the same connection under different names. When removing duplicates, compare the protocol, address, port, and key transport settings—not just the name. If the client offers deduplication, check which fields it compares and keep a recoverable copy before proceeding.

Automatic updates should track changes at the source, not refresh the list constantly. Set a reasonable interval based on how often subscriptions change and how you use them. If several sources update at once, it can be harder to identify the cause of an error. Pause automatic updates for the relevant groups while troubleshooting to keep the test environment stable. Resume them when the issue is resolved, so remote changes do not happen during local validation.

Test the update path and connection path separately

Subscription updates may use a direct connection or the current proxy, depending on the client settings. If your current proxy depends on a subscription that can only be updated through that same proxy, prepare a recovery path in advance. Do not make an untested server the only update route and then delete the last working entry; that can lock you out of both subscription management and connectivity.

Test one group at a time. Record the update method, the stage where it fails, and whether the old entries remain; then test another route for comparison. For certificate errors, check the system time and network instead of disabling certificate validation. A captive portal, modified response, or incorrect redirect can cause an import to fail. An empty list in the client is the result, not the cause.

After updating, check which server is currently selected. If the source removed or replaced an entry, the client may keep the old selection or prompt you to choose again. “Update succeeded” does not mean the active connection now uses the latest settings. Check the selected entry in the main window, reconnect, and review the destination address and configuration source in the logs.

ActionPrimary impactCheck afterward
Update one groupServer entries generated from that sourceFilter results, current selection, key settings
Change a group’s filterEntries visible or retained after importWhether a known entry was filtered out by mistake
Switch the active serverOutbound used by new connectionsWhether app connections need to be reopened
Delete a subscription sourceFuture updates and associated entriesWhether existing entries can still be managed and restored

Keep manual entries separate from subscription entries. Manual entries are useful for confirmed settings, but they do not receive corrections from the source, so you must maintain them yourself. Record why you changed an entry and which fields you changed; do not store credentials in its notes. For a temporary test, delete the copy when you are done so you do not have to guess months later which entry is still maintained by its source.

Plan backups, migration, and sensitive-data handling

Before backing up client settings, check what the export includes. It may contain subscription URLs, server credentials, custom routing, and interface settings. Treat backups as sensitive and store them somewhere access-controlled. Create a separate, redacted support file containing only the error and necessary fields. Do not upload a complete export to a public forum or share a QR code containing access parameters.

When moving to another device, install the client for that platform first, then import only what you need. Do not assume v2rayN desktop management settings can be read directly by an Android client. Generic subscription data and client-specific settings are different types of data. Restore one source and verify the connection first; then migrate routing, DNS, and traffic-capture settings. This avoids carrying over device-specific routes and permissions.

If you suspect a subscription URL has leaked, use the source’s management tools to replace its access credentials, then update your local entries. Changing the group note does not revoke access through the old URL. Confirm that every device has been updated and disable old scheduled tasks and cached copies. The client cannot revoke access on behalf of the subscription provider; access must be managed where the URL was issued.

Use a consistent maintenance sequence: verify the source, then filtering, then the connection. If several groups fail at once, check shared dependencies such as system time, network access, and the current proxy. If only one group fails, focus on its URL and response format. You can also browse related issues in the FAQ under setup and troubleshooting to avoid mistaking a source problem for a damaged client.

Custom Outbounds

Connect routing rules to outbounds with tags

Outbounds define how connections leave the core, and routing selects one by its tag. A tag is only an internal reference name; it has no special behavior. Naming an outbound direct does not make it a direct connection—the protocol and its settings determine what it does. Check the outbound object first, then the routing reference. Matching tag names are necessary, but not sufficient, for a valid configuration.

A GUI client usually generates a proxy outbound for the selected server, along with direct and blocking outbounds. Before adding a custom object, check whether the client expects an appended snippet, a complete configuration replacement, or a dedicated custom-configuration entry. A partial snippet in a full-configuration field will be missing required sections such as inbounds. Conversely, putting a full configuration in an append area may create duplicate definitions.

The following are common direct and block outbound snippets for native V2Ray or Xray configurations. They illustrate the tag structure; check for existing tags before merging. The example contains no proxy-server credentials and is not a complete client configuration. Generate proxy outbounds from a verified server entry to avoid omitting transport or security settings when writing them by hand.

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

Test one route before adding more

After adding an outbound, start with one narrow, explicit rule that references it. Choose a test target you can control, confirm that the core starts, the tag exists, and the rule matches, then consider expanding its scope. Do not replace the route for all traffic at once. If the configuration is wrong, every app failing at the same time leaves fewer clues and may also cut off subscription updates and help pages.

Direct outbounds still depend on DNS and the system network. They do not bypass the firewall or guarantee use of a particular physical interface. If you need to bind an interface or specify a source address, confirm that the current core supports the option and that the system permissions are sufficient. Verify that the address belongs to this device. Copying an interface name or address from another device will usually break the connection, not reproduce its route.

A proxy chain is not created simply by defining multiple proxy outbounds. Connections pass through multiple stages only when an explicit handoff is configured; ordinary routing generally selects one outbound. Before building a chain, verify each stage independently, including its DNS resolution, transport protocol, and authentication requirements. Any failed stage affects the whole chain. Read logs stage by stage rather than looking only at the final timeout.

Pay particular attention to UDP and multiplexing. An outbound that carries web traffic may not support every datagram flow, and a protocol that supports multiplexing does not mean it benefits every app. Keep the defaults initially; test changes only when you have observed connection-setup overhead or a compatibility issue. Mux is not a guaranteed speed boost, and multiplexing fields from different cores are not interchangeable.

Handle default outbounds, loops, and compatibility

Without an explicit fallback rule, the default outbound may depend on object order. Inserting an object can change the route for unmatched traffic even if no existing rules changed. Note the default behavior before editing, then test a target that should not match any earlier rule. To make the intended default reliable, use a fallback method supported by the current core rather than relying on incidental ordering.

Avoid circular references between outbounds, and make sure an outbound’s connection is not captured again by the local proxy inbound. The first issue is caused by handoff relationships in the core configuration; the second may come from the system proxy, TUN, or app proxy settings. Both can appear as repeated connection attempts and timeouts. Map each next hop until you reach the actual network exit, and account for any arrow that points back to the start.

Save the configuration before switching cores, then check the protocol, transport, security options, and resource formats one by one. V2Fly and Xray share some configuration concepts, but not every extension is compatible. v2rayNG and v2flyNG are not the same runtime environment just because their names are similar. If a core reports an unknown field, correct the configuration for the features it supports; do not simply delete the line without accounting for its purpose.

When maintaining a custom configuration, keep each tag’s purpose in a separate note; comments in strict JSON can cause parse errors. Check brackets, commas, quotation marks, and duplicate keys when saving. Change one logical unit at a time, then verify network access after the core starts. Passing syntax checks does not mean the outbound is reachable. To choose a different client, see the downloads page for platform and core details.

To remove a custom outbound, first remove or update rules that reference it, then delete the object and check the default route. Removing an outbound while leaving its tag in a rule can make startup or rule matching fail. After rolling back, reconnect the test app and confirm that the client is generating the expected configuration; the interface may look restored while the runtime file still contains the old settings.

Configuration Validation & Layered Rollback

Keep a reproducible validation baseline

Before making advanced changes, preserve a combination you have confirmed works: the client, core, server entry, system proxy state, routing preset, and DNS method. Record the purpose and key options without putting sensitive addresses in public notes. A baseline is a point of comparison, not a guarantee that things will always work. Revalidate it when the source changes and note what is different.

Change one layer at a time: subscriptions and servers first, then routing, DNS, traffic capture, and finally virtual mapping. Validate each layer before moving on. If you switch cores, enable TUN, add FakeDNS, and replace rules all at once, it is nearly impossible to identify the cause of a failure. Efficient advanced configuration comes from reducing variables, not entering as many settings as possible.

Build a fixed test set: one destination that should go direct, one that should use the proxy, one LAN service, and the app with the actual issue. Use the same targets each time and make sure no old connections are being reused. Record whether each request entered the client, resolved successfully, matched an outbound, and where it failed. Do not invent speed estimates or rely on impressions alone.

Locate failures along the connection lifecycle

First check whether the core starts normally. Configuration parse errors, failed resource loading, and occupied listening ports all happen before an external connection is attempted. Changing servers will not fix them. Check the most recently changed objects and the first error in the logs; fix the earliest failure. Later retry messages are often downstream effects, so do not be distracted by a repeated message at the end.

After startup succeeds, confirm that app traffic enters the core. If there is no corresponding inbound record, check app proxy settings, the system proxy, TUN routes, and per-app lists. Only investigate DNS and rule matches after you can see the request entering. Some log levels do not show every connection, so increase verbosity temporarily if needed; “not shown” does not prove “did not happen.”

Once the request enters, distinguish DNS, connection, and handshake errors. A resolution timeout points to the resolver path. A failed connection may involve the address, port, outbound, or firewall. TLS errors also warrant checking the server name, system time, and certificate chain. Do not bypass an error by disabling verification: that changes the connection’s security conditions without explaining why the original configuration failed.

Observed resultCheck firstLeave unchanged for now
Core fails to startConfiguration syntax, resources, port conflictsRemote server selection
App request does not enter the coreProxy inbound, traffic-capture scope, app settingsDomain category rules
Resolution succeeds, but traffic uses the wrong outboundRule order, default outbound, domain recoverySubscription URL
Rules match, but the handshake failsProtocol settings, system time, transport, certificateVerified match conditions
System remains abnormal after exitLeftover proxy settings, DNS, virtual interfaces, routesAll server entries

If only some apps fail, check whether they use their own DNS, a fixed address, UDP, or a different proxy protocol. If only background activity fails, check sleep behavior, network switching, and background restrictions. For persistent background issues on Android, see v2rayNG battery optimization and background settings. Do not treat an app lifecycle issue as a reason to re-enter every connection setting.

Roll back narrowly and organize evidence

Roll back in reverse order of the most recent changes. First undo added rules or custom snippets, then restore the DNS method, and finally exit TUN. With FakeDNS, also clear virtual-address caches; with the system proxy, check its actual system state. Retest immediately after each rollback. If the issue disappears, narrow it to that change and its dependencies instead of removing other working settings.

If the network is still broken after a normal exit, first check whether the system proxy points to a local port that is no longer open, then check DNS and the default route. Do not clear every network setting; that could affect static addresses, corporate networks, and virtual machines. Prefer the client’s normal cleanup procedure and restore system settings one at a time, keeping the original values for comparison.

Keep a short record of the changes that worked: which setting you changed, why, what you tested, and how to undo it. Do not save a configuration file without noting where it came from or what it does. If the client interface or core behavior changes later, your notes will help you rebuild the setup without assuming every old field still means the same thing.

After troubleshooting, restore the normal log level, remove temporary test entries, and re-enable automatic updates only if needed. Review the Quick Start for the basic workflow, the glossary for terminology, and the FAQ for common issues. Keep the configuration clear, verifiable, and easy to roll back before expanding it for other uses.