Configuration Reference · JSON Guide

V2Ray Configuration Reference

Structure, tags, parsing, and policies—from client-generated configs to pinpointing issues field by field.

For your first setup, importing a subscription, or enabling a proxy, start with the Getting Started Guide. This page is a detailed reference: it explains how settings map to JSON, how the modules depend on one another, and how to verify changes. Examples follow common Xray and V2Fly JSON structures; for kernel-specific options, consult the documentation for the kernel you use.

JSON Structure Overview

Configuration Objects and the Connection Path

A V2Ray configuration file has a JSON object at its top level. Inbounds receive application connections, outbounds send them, routing selects where they go, DNS handles name resolution for requests covered by the config, and policies control certain connection limits and statistics. These modules are not scripts that run in file order; the kernel reads them and builds a runtime configuration. To understand a config, trace which inbound handles a request, which rule matches it, and which outbound it reaches—not just whether a particular field is present.

It is also important to distinguish the GUI client from the kernel. v2rayN, v2rayNG, and v2flyNG manage nodes, subscriptions, and proxy controls; the kernel behind them establishes connections. A single client setting may generate several JSON fields or change only an operating-system setting. The system proxy toggle is usually the latter: an HTTP inbound in the config alone does not mean the browser is using it. The examples below start with a local SOCKS inbound and a direct outbound to establish a complete baseline and verify the basic connection path.

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": []
  }
}

Types, Arrays, and Tag References

JSON distinguishes field types. In this example, the port is a number, switches are Boolean values, tags and addresses are strings, and multiple inbounds and outbounds go in arrays. Strings require double quotes; the last item must not have a trailing comma, and standard JSON does not allow comments. Being able to open a file in an editor does not mean the kernel can parse it. Syntax errors and incorrect field meanings are separate issues. Check brackets, quotes, and types first, then confirm the protocol supports the settings in question. This helps avoid mistaking a simple syntax problem for a network failure.

Tags connect modules. An outbound tag in a routing rule must exactly match the tag on the outbound object; even a difference in capitalization can break the reference. Use short, clear, unique names—for example, separate tags for direct, blocked, and remote proxy traffic. Do not infer a tag's meaning from its position in an array. Unmatched traffic usually uses the first outbound, so changing outbound order alone can change the default behavior. When copying a snippet, check both the reference and its target.

FieldMain roleCommon dependencies
inboundsReceives application connectionsListen address, port, and authentication method
outboundsDirect, proxy, or blockProtocol and transport parameters
routingSelects where connections goOutbound tags and rule order
dnsKernel-level domain name resolutionResolution policy and query path
policyConnection policies and statistics switchesUser levels and statistics modules

Merging Snippets and Saving Changes

When merging configurations, keep only one copy of each top-level field. Add to or edit an existing outbound array instead of defining another array with the same name. Parsers may handle duplicate keys differently, so a file may appear to save successfully while only the later value is actually read. Put fields at the correct level within their objects—for example, transport settings belong to the relevant outbound, not the top-level routing object. For optional fields, keep the kernel defaults unless you need a specific behavior; there is no need to fill in every documented parameter.

For desktop use, v2rayN is the recommended choice for managing standard nodes, but do not overwrite a temporary config generated at runtime. Selecting a node, updating a subscription, or restarting the service may cause the client to regenerate that file. First confirm whether you are editing a custom config or changing settings the client saves persistently. Keep a working copy before testing, and note the fields changed and the expected result. Afterward, check the logs for the actual listen port and selected outbound. Add routing and DNS only after the configuration structure is stable; this makes problems much easier to isolate.

inbounds: Inbound Configuration

Listen Address, Port, and Application Access

An inbound defines where the kernel receives connections and which protocol it uses to interpret them. For typical desktop use, SOCKS and HTTP are common local entry points. An application must send requests to the inbound directly, or have them routed there through a system proxy, virtual network interface, or similar mechanism. A loopback listen address accepts connections only from the same device; listening on all interfaces may also expose the port to devices on the local network. The latter requires careful consideration of the firewall, authentication, and network boundaries. Do not widen the listening scope just to troubleshoot, especially on public networks or shared devices.

The port must match the proxy port configured in the application and must not already be in use. A port conflict usually appears in the startup log as a bind failure; switching nodes will not fix it. Close the other proxy client or change the local port in the GUI settings, then update the application to use the same port. SOCKS and HTTP ports are not interchangeable labels: sending an HTTP request to an inbound that expects a SOCKS handshake will fail early, often with nothing more than a browser message saying the proxy server is unavailable.

{
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    },
    {
      "tag": "local-http",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ]
}

Authentication, UDP, and Domain Information

A local, single-user setup often uses a SOCKS inbound without authentication, but that does not make unauthenticated listening appropriate on every address. When sharing access with other devices, consider who can reach the port, whether the client protocol supports the required authentication, and whether the firewall restricts its source. Authentication is only one layer; it does not replace a sensible listening boundary. HTTP inbound settings have a different structure from SOCKS settings, so do not copy an authentication block from one to the other. Use the format supported by the protocol and kernel in use, then verify that the application can complete the handshake.

The UDP switch on a SOCKS inbound means that the entry point can handle the relevant UDP requests; it does not guarantee that UDP will work end to end. The result depends on whether the application uses SOCKS UDP association, whether the remote protocol and service support it, whether the outbound allows it, and whether the firewall permits it. Testing a browser through the system proxy does not cover every UDP use case. If web pages load but a particular app fails, first determine whether the failure involves TCP connections or UDP traffic, then decide whether the access method needs to change. Do not attribute every symptom to node quality.

The inbound method can also affect where domain names are resolved. An application may pass a domain name to the SOCKS inbound or resolve it to an IP address first; an HTTP proxy can usually read the domain from the request target. If routing depends on domain rules but the inbound receives only an IP, the result may differ from what you expect. Protocol sniffing can recover domain clues from some recognizable traffic, but not all traffic contains that information. Sniffing may also affect destination selection, so enable it only when there is a clear need. It is not a catch-all guarantee that domain rules will match.

v2rayN TUN Mode and the System Proxy

v2rayN TUN mode and a regular local inbound solve different problems. The system proxy provides an entry point for applications that follow the system settings. TUN mode uses a virtual network interface to capture traffic covered by its routing rules, which can help with applications that ignore the system proxy. It involves a virtual adapter, routes, and permissions; it is not simply a field you add to the inbound array. Client implementations and generated configs can vary by platform, so consult the client’s TUN settings separately from manual kernel configuration.

Before enabling TUN, confirm that the regular proxy path works, then check the required permissions and possible conflicts with other network software. Use one primary traffic-capture method at a time. Multiple virtual adapters or proxy processes changing routes simultaneously can create loops or make the DNS path unclear. If access still fails after turning TUN off, check whether the system proxy is still set, whether the virtual interface has been restored, and whether the app has cached proxy settings. For different browser and terminal connection methods, see Troubleshooting System Proxy Issues in Browsers and Terminals. Do not judge the entire inbound by the behavior of just one application.

outbounds: Outbound Configuration

Default Outbound and Connection Destinations

An outbound describes how a request leaves the kernel. A direct outbound connects to the destination from the local device; a block outbound terminates matching requests; a proxy outbound first connects to a remote service, which then handles the destination connection. The outbound array can contain all of these, and routing determines which one is used. A common setup puts the proxy outbound first so traffic that matches no special rule goes through the proxy. The baseline in Chapter 1 deliberately puts direct first and is only for testing local access. Before copying an example, check the default outbound so you do not mistake a connection-test config for a remote proxy setup.

Check the remote address, remote port, user ID, and transport together. A correct address with the wrong port usually cannot reach the service. A successful network connection with mismatched user parameters may be rejected at the protocol stage. Correct user parameters with the wrong transport settings will also fail to establish the expected connection. The node name shown in the client is just an alias; it does not prove these fields match. Compare the full parameters supplied for the node in the editing interface, paying particular attention to whether the transport path, service name, or security settings were lost during import.

{
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "example.com",
            "port": 443,
            "users": [
              {
                "id": "00000000-0000-0000-0000-000000000000",
                "encryption": "none",
                "level": 0
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "example.com"
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ]
}

VLESS Protocol, Transport, and Security Layer

In a VLESS user configuration, the encryption field commonly uses the value shown in the example, but that does not mean the entire connection lacks a security layer. Protocol, transport, and transport security are three separate dimensions: the protocol defines how proxy requests are represented, the transport determines what kind of connection carries them, and the security layer protects that connection. The example above uses TCP and TLS only to show how the fields relate; it does not represent a real service. If your service uses a different transport or security setup, change the fields to match its parameters. Do not combine fields from unrelated setups in one object.

The V2Ray protocol you can use is determined first by the server configuration and the capabilities of the current kernel—not by freely changing names in a client menu. VMess, VLESS, Trojan, and Shadowsocks use different authentication and parameter structures; changing only the protocol field will not convert one into another. VMess also has conditions such as device time to consider, and no single setting can sum up the security design of every protocol. For a comparison of the basics, read VMess vs. VLESS: Key Differences, then choose the client option that matches the actual node parameters.

The TLS server name must match the certificate and server configuration. The remote connection address can be a domain or an IP, but it is not always the same as the name used for certificate verification. Being able to open an address in a browser does not prove that it serves the required proxy protocol. If you see a certificate error, check the system time, name, and certificate chain, and verify where the parameters came from. Do not disable certificate verification just to hide the warning: that masks a real configuration issue and weakens connection verification.

Kernel Compatibility and Preserving Parameters

Xray and V2Fly share some configuration concepts, but that does not mean every field, transport, or extension is interchangeable. v2rayN lets you select a kernel, while v2rayNG and v2flyNG target different kernel families; check that the features your node depends on are supported before switching. When you encounter an unknown field, an unsupported protocol, or a startup failure, first check the capabilities of the kernel in use instead of repeatedly changing the remote address. For ecosystem context, see How Project V, V2Fly, and Xray Relate.

After importing a node, preserve the original parameters the client recognizes and check them one by one before customizing anything. Some interfaces hide fields that do not apply to the selected transport; hidden fields are not necessarily included in the generated config. Inspect the generated outbound to confirm that parameters appear at the right level. Change one setting per test and save the failure log with its timestamp. If you change the protocol, transport, and kernel all at once, even restoring the connection will not tell you which change made the difference.

routing: Routing Rules

Rule Order and Matching Conditions

Routing connects connection attributes to outbound tags. Common attributes include the destination domain, destination IP, destination port, network type, and inbound tag. Rules are usually checked in order, and the first match determines where the connection goes, so put specific exceptions before broad rules. Traffic that matches no rule usually goes to the first outbound. Understanding the default outbound and rule order matters more than memorizing extra fields: a broad rule near the top can prevent later, more specific rules from ever handling the relevant requests.

Within a single rule, conditions from different categories generally all have to match; multiple values in an array for the same category offer alternatives. For example, specifying both an inbound tag and a destination domain means the rule applies to matching domain requests received through that inbound—not to a request that matches either condition alone. Do not cram separate intentions into one object. If you need to express two independent cases, use two rules. They are easier to explain and make it easier to identify which rule changed the outbound in the logs.

{
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": [
          "full:blocked.example.com"
        ],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "ip": [
          "10.0.0.0/8",
          "172.16.0.0/12",
          "192.168.0.0/16"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "domain:example.com"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

Domain Rules and IP Address Rules: Where They Differ

An exact domain match in the example applies only to the specified name; a domain rule covers the relevant domain and its subdomains. The first rule blocks one specific subdomain, then a later rule sends other matching requests for the same parent domain direct, demonstrating why precise rules come first. Do not assume the prefixes work like ordinary strings, especially for regular expressions: an overly broad expression can match unrelated domains and make the rules harder to maintain. Start with an exact domain or domain suffix. Use a regular expression only when you need a more complex pattern, and test both matching and non-matching targets.

A private-address rule matches only destination IPs that actually reach the routing check. If a request contains a domain name and the routing policy does not resolve it, a private IP range rule alone may not identify that the domain points to an internal service. Add a domain rule for known internal names, or choose a domain-resolution policy that performs IP checks if needed. A domain can also resolve to multiple addresses, and IPv4 and IPv6 results can differ. A rule matching in one test therefore does not guarantee the same route for every address family or resolution result.

The routing domain strategy and the domain strategy on a direct outbound act at different points. The routing strategy mainly controls whether names are resolved when evaluating rules; the direct outbound strategy mainly affects address selection when connecting directly. Confusing them can lead to the mistaken conclusion that routing should match because a resolution strategy was set. With on-demand resolution, understand the trigger conditions and the current kernel implementation to avoid unnecessary DNS queries. If a domain rule expresses the intended behavior clearly, there is no need to resolve every request just to match an IP.

Rule Resources and Verifiable Changes

Some routing configurations reference geographic IP or domain-category resources. Those references depend on resource files, resource names, and update methods provided by the client; adding a reference to JSON does not make the resource appear. Missing resources can cause startup errors, and differences in category data can change what matches. This page uses explicit domains and IP ranges for clarity. Before importing external rules, check which resources they require and whether they work with your kernel, then inspect the references in the generated config. A rule's title alone does not establish compatibility.

After changing routing, test one destination that should go direct, one that should use the proxy, and one that should be blocked. Check the outbound tag in the connection logs. Browser caches, existing long-lived connections, and application-level DNS can make it look as if nothing changed; close old connections or restart the app if needed. If all connections fail, first remove the last broad rule you added, then verify tag spelling and the default outbound. Rule count is not a measure of quality. A small set of rules that is easy to explain and test is easier to maintain and move to another client.

dns: Domain Name Resolution

First, Identify Where Resolution Happens

Start by classifying DNS issues according to where resolution occurs. An application may use the system resolver or have its own built-in resolution method; a local proxy may receive a domain and resolve it in the kernel; a remote service may also resolve the destination domain. These paths can coexist. The top-level DNS object only controls relevant requests that use the kernel's DNS features; it does not automatically take over every domain lookup on the device. So if browser results do not change after a DNS edit, that alone does not mean the setting failed. First confirm whether the browser's requests use that resolution path.

Keep resolution of the connection destination separate from resolution of the proxy server address. An outbound must first locate the remote service; if its address is a domain, resolving it may be necessary at startup or when connecting. The domain of the website you visit may then be resolved elsewhere. Requiring every query to go through a proxy connection that has not yet been established can create a startup dependency loop. When planning DNS paths, identify how the remote service address is resolved, how the resolver is reached, and whether essential resolution is still available if the proxy fails. Do not simply pick the server name that looks most familiar.

{
  "dns": {
    "hosts": {
      "service.example.com": "192.0.2.10"
    },
    "servers": [
      "localhost"
    ],
    "queryStrategy": "UseIP"
  }
}

Static Mappings, Servers, and Address Families

This snippet establishes a baseline with the local system resolver and shows the structure of a static domain mapping. The example address is reserved for documentation and is not a real service destination; remove this teaching mapping when testing real websites. Static mappings are useful when you know the destination address and need a fixed result, but they are not a long-term substitute for resolving services whose addresses change frequently. A domain's addresses may vary by region, load, or service migration. Fixing an outdated address can break connections or bypass normal address selection.

A resolver can use the system DNS or another form supported by the kernel. Different forms may use different protocols, ports, and connection paths, so the server address alone does not tell you whether the query goes through a proxy. If you configure an HTTPS-based resolver, also consider how its hostname is resolved and how it connects. Some kernels distinguish between local direct queries and queries that can be handled by routing; check the behavior of the kernel you use. Verify a simple, known-reachable resolution method first, then add domain-routing rules. This reduces the risk of several dependencies failing at once.

Address-family policies determine which IP types are queried or accepted, but they cannot give a network IPv6 connectivity it does not have. If you select only one address family and the destination has no matching record, you may lose a usable address. For sites that load slowly or resolve successfully but time out, check whether the returned address family is reachable from your device, through the remote service, and via the final outbound. Record the resolution result before changing the policy, then compare it against the same domain afterward. One successful visit is not enough to conclude that an address family is better in every situation.

Domain Routing, Caching, and Coordination

More advanced DNS configurations can assign specific domains to particular resolvers and control fallback behavior. Whether the resolver tries another server after a failed response, an empty result, or a filtered answer can affect both the final result and response time. Check the server object fields supported by your kernel alongside its fallback logic; “prefer” does not mean “use only.” If you set an address-range filter, also confirm that the expected result could fall within that range, or a valid answer may be treated as unsuitable.

Keep DNS and routing semantics consistent. If an internal domain should connect directly, the resolution path must return an internal address, and routing must recognize the relevant name or address. If a connection should go through a remote service, make sure the resolution location does not interfere with the expected behavior. Resolver selection, routing outbound selection, and a browser's secure DNS settings are separate controls, not one switch. For troubleshooting, hold two constant and change only the third, then confirm the result using logs and application behavior.

Caching can hide the effects of a change for a while. Caches may exist in the browser, operating system, kernel, or remote resolver, and restarting one process does not necessarily clear every layer. To test a change, first confirm that the config has been reloaded, close existing connections, and restart the target app if needed. Distinguish resolution failures from connection timeouts and certificate errors. If only one app is affected, check whether it uses its own resolution method. With a virtual network interface, also check whether the client handles DNS separately; otherwise, you may keep changing a top-level object that the actual requests never use.

policy: Policies and Statistics

User Levels and Connection Time Limits

The policy module defines some connection behavior and statistics switches; it does not decide which node a request uses. A common structure sets policies by user level and statistics options for the system as a whole. A user level is a configuration reference, not an account permission, paid tier, or node quality rating. A policy only applies when the relevant protocol user object supports and uses that level. If a level is defined but no relevant user refers to it, the policy will not automatically apply to every connection.

Connection establishment, idle keep-alive, and waiting after a half-close are different stages. A handshake timeout limits how long connection setup can wait; an idle timeout applies to an inactive connection; a half-close timeout allows time for data in the other direction to finish. Lower values may free resources sooner, but can also cause frequent disconnects on slow networks, long polling, or apps that remain idle for a while. Adjust settings in response to a specific, reproducible symptom. Do not lower every timeout at once and then mistake the resulting disconnects for an unreliable remote service.

{
  "policy": {
    "levels": {
      "0": {
        "handshake": 4,
        "connIdle": 300,
        "uplinkOnly": 2,
        "downlinkOnly": 5,
        "statsUserUplink": true,
        "statsUserDownlink": true
      }
    },
    "system": {
      "statsInboundUplink": true,
      "statsInboundDownlink": true,
      "statsOutboundUplink": true,
      "statsOutboundDownlink": true
    }
  },
  "stats": {}
}

Statistics Switches, Identity, and How to Read the Data

The time fields in the example use seconds, following common kernel conventions. The values illustrate structure; they are not a recommended combination for every network. Level-object keys are strings, while the level in a user object is usually a number, so their types differ in the config. Keep the client defaults unless you have a reproducible timeout issue to address. Support, units, and defaults for buffer or connection-management fields can vary by kernel, so a set of parameters found online is not a universal optimization.

Enabling the statistics module and being able to read statistics are two separate things. An empty statistics object enables the module; policy switches control which directions or objects are collected, but do not automatically create charts in the interface. Reading the results also requires client support or a statistics interface supported by the kernel. A client may collect the speed or traffic it displays through a different mechanism. So if user statistics are missing from the interface, the module may still be working. First confirm what data the client is trying to read and whether the required interface exists.

Per-user statistics usually also depend on a recognizable identity field in the relevant user object and on protocol support; a level switch alone may not produce the expected entries. A basic local SOCKS inbound does not acquire a remote user identity just because level zero is specified. Statistics for inbounds, outbounds, and users reflect different observation points, so do not add them together indiscriminately as actual network usage. Encapsulation overhead, transport layers, and multiple connections all affect comparisons. Statistics are more useful for tracking trends and identifying traffic sources than for matching a server-side bill.

Statistics Interfaces and Access Boundaries

If you need to configure an administration interface manually, consult the interface model and service list for your kernel, and restrict the listen scope to what is required. The interface entry point, its routing, and service names often need to be configured together; adding a policy block alone does not create an accessible management channel. Do not expose the interface on every network adapter just to connect a statistics tool. This channel is not a regular proxy entry point. If the GUI client already manages the relevant interface, use its existing display where possible to avoid creating another endpoint that conflicts with an existing port.

Verify policy changes with repeatable behavior. For idle disconnects, record the time an app establishes a connection, how long it remains idle, and when it disconnects. For handshake failures, note whether the remote port was reached and whether the connection advanced to the security or protocol stage. Change a policy only when the evidence points to the stage it controls. If the real issue is DNS failure, routing to a block outbound, or incorrect node parameters, increasing timeouts only makes users wait longer; it will not fix the connection. For unusual resource use, first check where the connections are coming from and whether traffic is looping.

Restore diagnostic switches you no longer need after testing. Verbose logs and large numbers of statistics entries increase the cost of ongoing monitoring, and saved data may reveal browsing habits. Not every module described in a configuration guide needs to stay enabled. In a stable setup, keep only options with a clear purpose. On mobile, also distinguish policy-driven connection cleanup from operating-system background restrictions: extending the kernel's idle timeout will not prevent the system from suspending an app in the background. Check the app's permissions and battery settings instead.

Subscriptions and Client-Generated Configuration

A Subscription Is Not a Complete Configuration

Subscriptions mainly provide node information to a client. The complete runtime configuration is usually generated by the client from the selected node, local inbounds, routing, DNS, and other settings. Subscription formats vary in what they can carry: some describe nodes only, while others include more configuration structure. Whether the client accepts and preserves that content also depends on how it is imported. Do not treat a subscription URL, a share link, and a complete JSON file as the same kind of resource. First identify what you have, then use the appropriate subscription update, clipboard import, or custom configuration option.

A typical v2rayNG subscription import involves creating a subscription group, entering a name and URL, saving it, running an update, and then checking that nodes appear in the group. v2rayN uses a similar approach with subscription groups. The name helps identify the source; the URL retrieves the actual content. One cannot replace the other. After an update succeeds, you still need to select a node and start the connection. Downloading subscription data does not mean the remote service is available, and it does not turn on the system proxy or mobile VPN access. Check each step separately.

{
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth"
      }
    }
  ],
  "outbounds": [
    {
      "tag": "selected-node",
      "protocol": "freedom",
      "settings": {}
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "local-socks"
        ],
        "outboundTag": "selected-node"
      }
    ]
  }
}

The object above uses a direct protocol to stand in for a selected outbound; it illustrates the generated structure, not a subscription format. A real client converts the selected node into the corresponding proxy outbound and combines it with local settings. The displayed node name may change while the client's internal outbound tag stays fixed, or the tag may vary by configuration mode. Do not write manual routing rules based only on the name shown in the node list; check the tag in the generated config. If the client provides a shared proxy outbound reference, follow its rules for editing it.

Update Boundaries and Custom Configurations

A subscription update may replace node parameters, add or remove nodes, or change aliases; the exact merge behavior depends on the client. Manual changes to subscription nodes may be overwritten by the next update. To keep special nodes long-term, use a separate group or configuration if the client supports it, and note where it came from and why it was changed. Whether local routing and DNS settings change during an update also depends on the import mode. Updating nodes and importing a complete configuration are different operations; checking the actual runtime objects before and after is more reliable.

A custom full configuration suits users who need explicit control over its structure, but it may bypass some of the client's automatic generation. Selecting a node, choosing a routing preset, or changing the local port in the interface may not affect this file. Before switching to a custom mode, confirm who manages the inbounds and management interface, whether the client still adds fields automatically, and which file is loaded at startup. Do not expect every standard interface setting to be written into a full custom config. Establish clear ownership of the configuration before adding customizations.

ClientPlatformWhat to check
v2rayNWindows、macOS、LinuxKernel selection, generated config, system proxy, and TUN settings
v2rayNGAndroidXray parameter support, subscription updates, and VPN permissions
v2flyNGAndroidV2Fly parameter support and compatibility with existing nodes

Migration, Privacy, and Choosing a Client

When moving to another client, migrate nodes first, then set up local access and routing again. Do not assume every interface preset has an equivalent setting with the same name. v2rayN is recommended for desktop use; on Android, choose v2rayNG or v2flyNG based on the kernel you need. The same node parameters may behave differently depending on kernel feature support. Visit the client downloads page to choose the option for your system. When searching for a v2rayNG download, first check your device architecture. Architecture determines whether the app can install and run; it does not directly determine node protocol or routing behavior.

Subscription URLs often contain access credentials, so do not include the full link in public screenshots, chat logs, or bug reports. When reporting a problem, keep the error type, response status, and update time, but hide query parameters and user IDs. For a failed update, first distinguish between an inaccessible URL, an empty response, an unsupported content format, and a node parsing failure. These stages do not map directly to whether a proxy node can connect. If only some nodes are missing, check whether their protocols and transports are supported before reinstalling the entire client.

Set a reasonable automatic update interval. Updating too frequently creates unnecessary requests and can keep changing the test setup while you troubleshoot; updating too infrequently may leave outdated parameters in place. Choose an interval that matches how often the service changes and how you use it. A shorter interval does not mean a better connection. During troubleshooting, temporarily keep the node and configuration fixed, then resume regular updates after testing. For your first setup, follow the subscription steps in the Getting Started Guide. This chapter explains which modules may change after an update.

Configuration Validation and Troubleshooting

From Loading the Config to Application Access

Validate the connection path in order: confirm that the config parses, that the kernel starts and listens locally, that the application actually uses the entry point, and then check routing, DNS results, the remote connection, the protocol handshake, and finally the application itself. This order narrows the problem to a specific stage. “The website won't open” is not a diagnosis, and reinstalling the client is no substitute for troubleshooting. Knowing the last successful stage and the first failed one tells you whether to check the port, permissions, parameters, or network path next.

After making a change, first confirm that the new configuration is loaded. The client may still be running an old process or may generate a different file at startup, so the editor contents do not necessarily reflect the runtime state. Save the config, restart the service using the client's procedure, then check the startup log for the listening address, port, and kernel in use. If the log reports an unknown field, check compatibility; if it reports a bind failure, check the port. If there is no startup log at all, check whether the program started correctly. See Troubleshooting Client Crashes and Permission Issues for more help.

{
  "log": {
    "loglevel": "info"
  }
}

Log Details and Issue Categories

Temporarily enabling informational logs can help you follow the inbound and outbound path, but their content and detail depend on the kernel and client. Do not expect every rule to produce a match entry in a standard format, or interpret a single keyword without context. Read logs in chronological order: after the application starts a connection, is there an inbound entry? Is an outbound selected? Does the failure happen during resolution, connection setup, or the handshake? After troubleshooting, restore a suitable everyday log level. Before sharing logs, hide sensitive details such as destination addresses, subscription parameters, and user IDs.

SymptomCheck firstDo not change yet
Fails immediately on startupJSON syntax, kernel support, port conflictsNode speed test and application cache
No inbound entry for the applicationApplication proxy settings, inbound protocol, and portRemote user parameters
Name resolution failsActual DNS path and resolver reachabilityProtocol name
Remote connection times outAddress, port, network path, and firewallStatistics interface settings
Handshake rejectedUser parameters, transport, and security layer settingsLocal port display name
Only some destinations failRouting rules, resolution results, and address familyResetting every module at once

A single symptom can have several causes, so this table helps prioritize checks rather than assign a definitive diagnosis. A remote timeout may mean the network is unreachable or the port is wrong. A handshake error may result from a mismatched server name, inconsistent authentication, or missing transport parameters. Comparing against a known-working configuration is more effective than repeatedly adding unfamiliar settings. Keep the device, network, and test destination the same during comparison so a change in network conditions is not mistaken for a configuration fix.

V2Ray Node Speed Tests and Real-World Availability

V2Ray node speed tests use different methods. A port connectivity test only shows whether a connection to the target port can be established; it may not complete the proxy protocol. Testing access to a URL through the proxy is closer to actual app use, but still depends on the test site, DNS, and routing. A download test measures sustained transfer performance and uses data. One time value in the interface cannot represent the whole browsing experience. Compare nodes using the same method and target, and verify them in the applications you actually use. Do not make a long-term configuration decision based on a single ranking.

If a test succeeds but the browser fails, check whether both use the same inbound and route. Browser extensions, bypass lists, built-in DNS, and existing connections can change the request path. Terminal tools may use their own proxy settings or environment variables. Conversely, a working browser does not prove every application follows the system proxy. Check how each affected app connects and whether its requests appear in the kernel logs. If you need to capture more traffic, return to the TUN section on this page and assess the permissions and routing impact.

Rollback, Notes, and Stable Operation

Change only one related set of fields per test and write down the expected result. For example, adding a direct rule for a domain should change its outbound tag—not necessarily improve the speed of every connection. Changing the resolution policy should affect the address family or resolution path, not make an authentication error disappear. If the result differs from expectations, restore the last working config and check the rule's prerequisites. Keep brief notes on the fields changed, test destination, and observed result so you do not lose track of why the current config exists after several rounds of testing.

A stable configuration should have a clearly defined default outbound, a limited set of explainable rules, DNS that fits the actual access method, and appropriate boundaries for local listeners. Remove temporary teaching mappings, diagnostic interfaces, and test parameters, then restore subscription updates. If you still need to report an issue, include the client name, operating system, kernel type, failure stage, and redacted logs; do not publish the full config. Use this page's contents to look up specific modules, and follow the Getting Started Guide for routine setup. This keeps the configuration maintainable and avoids rebuilding every setting from scratch whenever a problem occurs.