01 / concepts
Core Concepts: Map the Traffic Flow First
What the Client, Core, and Configuration File Do
The three objects most often confused in V2Ray are the graphical client, proxy core, and configuration data. v2rayN, v2rayNG, and v2flyNG are graphical clients that provide interfaces for importing subscriptions, choosing nodes, managing the system proxy, configuring routing rules, and viewing logs. Xray and V2Fly are cores that handle connections, protocols, transport, and routing. Configuration files pass listening ports, outbound parameters, domain rules, and DNS policies to the core. A change in the interface is usually converted into a set of configuration fields, which the core then reloads.
When troubleshooting, do not check only whether the client is running. Use this order instead: does the configuration exist, is it selected, did the core load it successfully, is the local inbound port listening, is application traffic reaching that port, did routing select the correct outbound, and did the remote connection complete? A break at any point appears in the browser as an inaccessible site, but each cause requires a different fix. Establishing this flow is the basis for every later decision.
How inbounds, outbounds, and routing Work Together
inbounds define how traffic enters the core. Desktop clients commonly use local SOCKS and HTTP listening ports; enabling TUN adds a virtual entry point for traffic from the system network layer. outbounds define where traffic leaves, whether through a remote configuration, a direct connection, or a blocked outbound. routing sits between them and uses the domain, IP, port, protocol, or inbound tag to choose an outbound.
Think of a request as “application → local inbound → routing decision → target outbound.” After a browser is configured with a SOCKS port, the request enters the local listener first. If a routing rule identifies the target as direct, it sends the request to the direct outbound; other requests go to the selected remote outbound. The tag used by the rules is the link between these sections. Names are customizable, but references must match. If a rule contains outboundTag: "direct", the configuration must include an outbound tagged direct.
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
}
]
}
}
Configuration, Nodes, and Subscriptions Are Different Objects
A node is a set of connection parameters, typically including the server address, port, user identifier, protocol, and transport settings. A subscription is an updateable data source that may return multiple nodes and grouping information. Client configuration is broader: in addition to nodes, it includes local ports, proxy mode, DNS, routing, logging, and interface preferences. Removing a subscription does not necessarily remove its existing local configurations, and switching nodes does not automatically change the system proxy mode. Before acting, confirm whether you are handling the subscription source, the configuration list, or the currently running instance.
For a field-by-field look at the configuration structure, continue with A Section-by-Section Look at config.json. It explains inbound, outbound, and routing tags side by side in a minimal configuration.
02 / client and install
Choose and Install a Client: Match the Platform, Then Check the Runtime Requirements
How the Three Clients Differ
For desktop platforms, v2rayN is the primary choice. It supports Windows, macOS, and Linux, with common entry points for configuration lists, subscription management, system proxy settings, routing, and TUN. The Windows download page offers both the desktop edition and the classic WPF edition. The desktop edition uses a cross-platform interface and suits users who want a similar workflow across desktop systems; the WPF edition follows classic Windows conventions with a more concentrated interface and system integration path. The key difference is the interface framework and platform integration, not a simple ranking of protocol capabilities.
On Android, v2rayNG is the first choice. It uses the Xray core and provides graphical controls for subscriptions, per-app proxying, routing, and connection tests. v2flyNG uses the V2Fly core and is an alternative when that core is required. The configuration lists of the two Android clients are not shared, so switching clients requires importing the subscription or configuration again. Do not copy one client’s internal database directly into the other; a subscription URL, share link, or standard configuration is better suited for migration.
| Platform | Preferred Client | What to Consider | Download |
|---|---|---|---|
| Windows | v2rayN | Choose the desktop or classic WPF edition based on the system environment and interface preference | Download for Windows |
| macOS | v2rayN | Choose the package for an Apple Silicon or Intel processor | Download for macOS |
| Android | v2rayNG | arm64 is the usual choice for modern devices; select the universal build if the architecture is unclear | Download for Android |
| Linux | v2rayN | Choose deb or rpm according to the distribution’s package system | Download for Linux |
Check the system architecture and existing instances before installing
Before downloading, confirm the processor architecture and operating system. On macOS, check the chip name in “About This Mac.” On Linux, run uname -m: x86_64 indicates x64, while aarch64 indicates arm64. Most recent Android devices use arm64, but choose a universal package when the architecture is unclear. A mismatched package commonly fails to start, is rejected by the installer, or exits immediately after launch. These issues should not be addressed by changing node parameters.
Before upgrading or switching interface editions, exit the old instance completely. A desktop client may keep a tray process running, so closing the main window does not always end it; use the tray menu to quit or verify that the process has stopped in the system task manager. If the old instance still holds a local port, the new instance will report a listening failure in its logs. Record the existing subscription URL, routing rules, and custom ports before migrating so you can tell which settings came from the old environment.
The Minimum Checks After First Launch
When opening the client for the first time, do not enable the system proxy and TUN at the same time. Use this order: confirm the interface works, import one configuration, select it, start the core, check the logs for a successful local listener, and then enable the system proxy for testing. Staged operation separates program startup issues from network interception issues. On Windows, follow the client’s stated runtime requirements if prompted; on Linux, launch once from a terminal and read the error if no menu entry appears; on macOS, confirm in Security settings that the app is allowed to open.
Installation does not mean the proxy is active. Client startup, core operation, and an enabled system proxy are three separate states. Opening the interface without starting a configuration creates no listener; a running core with the system proxy off affects only apps configured to use it manually; a configured system proxy with a stopped core sends requests to an inactive port. Understanding these states prevents installation problems from being mistaken for remote connection problems.
For a complete Windows installation path and common runtime fixes, see The Complete v2rayN Installation Guide for Windows. For help choosing between the two interface editions, see v2rayN Desktop vs. Classic WPF: Key Differences.
03 / subscription
Subscriptions & Configuration Management: Separate Importing, Updating, Selecting, and Running
The Four Steps After Importing a Subscription
Adding a subscription usually only saves a data source in the client. The full workflow has four separate actions: save the subscription details, update the subscription, choose a configuration from the results, and start the selected configuration. Some clients update immediately after saving, while others require you to run “Update subscription” manually. If the subscription was added but the configuration list is empty, first check whether an update was performed instead of deleting and adding it again. After updating, also check the active group and filters so an existing configuration has not simply been hidden.
A subscription name is only for local identification and does not affect connections. Use a short name that distinguishes its purpose and source; avoid putting dates in the name and changing it repeatedly. When several subscriptions exist, names should make the update scope clear. An update may replace configurations generated by that subscription, and manually edited node parameters may be overwritten next time. Keep long-term local changes in the client’s routing, DNS, or global settings. If a single configuration truly needs editing, copy it into an independent local entry and label its purpose.
How to Preserve a Working Configuration During an Update
Before updating, note the current configuration name and running state. Afterward, the client may preserve the selection using a unique identifier, or return to another entry if the configuration was replaced. The safest approach is to confirm the active configuration again after updating, then run a connection test. If the subscription returns empty content, do not repeatedly overwrite or delete every configuration. Check the HTTP status, response format, and parsing messages in the client log, and keep the last working configuration for comparison.
Update failures generally fall into three categories: “the URL cannot be requested,” “the request succeeds but the content cannot be parsed,” and “parsing succeeds but produces no usable configuration.” For the first, check the network path, system time, and whether the subscription URL is complete. For the second, verify that the response is a subscription format supported by the client and not a web page URL. For the third, check subscription groups, filters, and core compatibility. If the log shows a successful request but zero parsed items, repeatedly changing proxy modes will rarely help; inspect the subscription content and format instead.
Where Share Links, JSON Configurations, and Subscriptions Fit
A single share link is suitable for importing one specific configuration and checking its address, port, and transport settings individually. A JSON configuration suits cases that require full control over inbounds, outbounds, routing, and DNS. A subscription suits multiple configurations maintained by one source and updated periodically. All three can coexist, but avoid letting multiple sources create configurations with the same name; otherwise it becomes difficult to tell which one is running.
Before manually importing JSON, confirm whether it is a complete core configuration or a configuration fragment recognized by the client. A complete configuration usually contains top-level fields such as inbounds and outbounds, while a share link describes only one outbound connection. A graphical client may regenerate inbounds and routing from its own settings, so direct edits to a temporary runtime file are often overwritten at the next launch. Persistent settings should be managed through the client interface, a custom configuration entry point, or an explicit configuration-file management feature.
Basic Boundaries for Managing Subscription Data
A subscription URL may contain an access credential. Store it only in clients that need it, never on public pages, log screenshots, or shared documents. If logs must be shared for diagnosis, redact the complete subscription URL, server address, and user identifier; keep only the error type, status code, and event order. Client export functions may also include connection parameters, so confirm the export scope before sending anything.
In daily use, update subscriptions separately from upgrading the client. First verify the subscription update in the existing environment, then schedule the client upgrade; or upgrade the client first, confirm that the old configuration still works, and only then update the subscription. Changing both variables at once makes it difficult to identify whether the issue comes from the parser, core, or subscription content. Stable maintenance is not about frequent operations, but about giving each change one clear objective.
04 / proxy mode
Proxy Modes & Local Ports: Decide Which Apps Enter the Client
System Proxy, Manual Proxy, and TUN Coverage
The system proxy is the best mode for initial verification on desktop platforms. v2rayN sets the system proxy address to a local listening port, and browsers and apps that follow system proxy settings send requests to the client. The behavior is clear and easy to disable. The limitation is that some apps ignore the system proxy, while command-line tools and standalone environments may use their own settings. If the browser works but one app does not, first check whether that app follows the system proxy instead of assuming the configuration has failed.
A manual proxy is useful for precise testing. Enter 127.0.0.1 and the SOCKS/HTTP port explicitly in a browser, development tool, or command-line process. It does not affect other apps automatically, making it useful for verifying the local inbound. TUN operates closer to the system network layer and can receive more traffic from apps that do not support explicit proxies, but it also introduces virtual interfaces, routing tables, DNS interception, and permission issues. The recommended learning order is to make the system proxy work first and then move to TUN, rather than treating TUN as the default for a first connection.
Choosing Between SOCKS and HTTP Ports
A SOCKS inbound can carry TCP and, when allowed by the configuration, UDP. An HTTP proxy is mainly intended for apps that support HTTP CONNECT. Clients often create both local ports and may also provide a mixed inbound. When configuring an app, the protocol and port must match: entering a SOCKS port in a field that accepts only an HTTP proxy can cause connection or protocol errors, and the reverse is also true. No port number is mandatory; what matters is consistency among the client’s actual listener, system proxy setting, and application configuration.
The local listening address is usually 127.0.0.1, which accepts connections only from the same machine. Allow LAN connections only when another device explicitly needs access, and check the firewall and access boundaries at the same time. Opening a LAN listener requires more than changing the address; authentication and network scope must also be considered. For ordinary single-device use, a local-only listener is easier to manage and reduces the impact of changing LAN conditions during troubleshooting.
| Mode | Primary Coverage | Best For | Common Limitation |
|---|---|---|---|
| System Proxy | Apps that read system proxy settings | First connection and everyday browsing | Some apps ignore system settings |
| Manual SOCKS/HTTP | Apps with explicit proxy parameters | Port checks and per-app configuration | The protocol and port must match |
| TUN | More system network traffic | After the system proxy is stable | Requires attention to permissions, routing tables, and DNS |
Port Conflicts and Leftover System Proxy Settings
If the core reports that an address is already in use, another process has occupied the port it intends to listen on. Exit old client instances first, then identify the process. On Windows, run netstat -ano | findstr :10808 to obtain the process ID; on macOS, run lsof -nP -iTCP:10808 -sTCP:LISTEN; on Linux, run ss -lntp | grep 10808. Confirm what the process does before ending it or changing the client port; never terminate an unknown system service simply because it is using the port.
netstat -ano | findstr :10808
lsof -nP -iTCP:10808 -sTCP:LISTEN
ss -lntp | grep 10808
After changing the port, update the system proxy or application proxy settings as well. Changing only the client listener leaves the system proxy pointing to the old port: the client is running, but the app is still connecting elsewhere. A client crash can also leave the system proxy enabled. In that case, the browser continues trying to reach a local proxy even though the core has stopped. Reopen the client and disable the system proxy, or restore it manually in the system network settings. See How to Find and Fix a Port Conflict for the complete process.
05 / routing
Routing: Use Rules to Choose an Exit for Each Type of Traffic
Rule Order Matters More Than Rule Count
Routing rules are generally matched from top to bottom, and a match is sent to the specified outbound. More rules do not guarantee more accurate results; what matters is whether conditions are distinct, priorities are sensible, and the fallback outbound is clear. Put specific rules before broad ones. For example, if a domain belongs to a custom direct list but would also match a general proxy rule later, place the custom rule first. If the client provides preset routing modes, start with the preset closest to your goal and add only a few custom rules; this is easier to maintain than piling up large rule sets from scratch.
Common conditions include domains, IPs, ports, network types, protocols, and inbound tags. Domain rules work well with exact domains, suffixes, or GeoSite categories; IP rules suit private addresses and GeoIP categories; port rules target specific services; inbound tags let different local entry points use different policies. Do not treat a domain condition and the IP obtained after resolution as completely equivalent. Whether the domain is still available when routing runs depends on the DNS flow and the domainStrategy setting.
Three Outbound Types: direct, proxy, and block
Readable routing usually distinguishes at least three outcomes: direct means connect directly, proxy sends traffic through the current remote outbound, and block stops it. These names are only tags; actual behavior comes from the corresponding outbound protocol. References in rules must exactly match outbound tags. If the interface offers “direct,” “proxy,” and “block,” the client maintains the tags for you; when writing JSON manually, you must maintain those references yourself.
Private addresses should generally go direct so access to routers, printers, and LAN services does not take an unnecessary remote path. Traffic that needs blocking should use explicit conditions, avoiding overly broad domain keywords. Keep an understandable fallback policy: traffic that matches no rule should either use the proxy or connect directly, consistently with the client’s current mode. During troubleshooting, temporarily switching to a simpler global policy can show whether routing is the cause. Restore routing afterward rather than relying on the temporary mode.
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:private"],
"outboundTag": "direct"
},
{
"type": "field",
"protocol": ["bittorrent"],
"outboundTag": "direct"
}
]
}
}
How domainStrategy Works with DNS
AsIs tends to match the domain entering routing directly and does not perform extra resolution for IP rules. IPIfNonMatch attempts resolution when no domain rule matches, then continues with IP rules. IPOnDemand resolves more proactively when a rule may require an IP. The right choice depends on the rule structure. When domain rules dominate, AsIs is more straightforward; when GeoIP conditions are used heavily, IPIfNonMatch makes IP rules more likely to participate, but it also depends more on DNS results.
DNS and routing form a loop: DNS requests themselves need an outbound, and the resulting address affects subsequent routing. If name resolution uses an unsuitable network path, it may return an unreachable address. If a rule requires IP matching but no usable result is available, it will not match as expected. During troubleshooting, record separately who resolves the domain, which outbound carries the DNS request, and which routing rule receives the result. Do not change only the DNS address while ignoring the outbound path.
GeoIP and GeoSite Update Boundaries
GeoIP classifies IP addresses, while GeoSite classifies domain collections. When either database is outdated, new domains and address ranges may not fall into the expected category. If routing changes suddenly after an update, check for classification changes caused by the database version instead of immediately blaming the core. Keep high-priority custom rules limited and document why each exists. When a database update covers the scenario, remove duplicate rules to prevent future conflicts.
See GeoIP and GeoSite Database Update Guide for database roles, update entry points, and verification methods. To compare routing capabilities and supported platforms, see Client Comparison.
06 / tun
TUN Mode: Extend System Proxying to the Network Layer
When to Enable TUN
TUN receives system traffic through a virtual network interface. It is useful for apps that ignore system proxy settings, programs that need UDP, and desktop environments where configuring each app individually is undesirable. It does not improve connection quality or automatically fix incorrect remote parameters. If even basic pages fail under the system proxy, fix the configuration, port, DNS, or remote connection first. Otherwise, the added routing table and virtual interface only create more variables.
Before enabling it, complete three baseline tests: the current configuration starts successfully; at least one app can access the network reliably through the system proxy; and the client log has no continuing connection or resolution errors. Then disable the system proxy, or handle the relationship as the client recommends, before enabling TUN. Keep the default stack and MTU during testing. Do not change DNS, strict routing, bypass rules, and interface parameters at the same time. Adjust an option only after confirming a specific problem with the default configuration.
Virtual Interfaces, Routing Tables, and Permissions
TUN creates a virtual network interface and changes system routes, so desktop systems usually require the relevant permissions. Without them, the virtual interface or route may fail to be created, or the client may show TUN as enabled while no traffic enters it. Use the client log to identify the exact failed step, then address it according to the system’s permission model. Repeatedly clicking the toggle can leave several temporary interfaces or residual routes and make the symptoms harder to interpret.
The routing table determines which destinations enter the virtual interface, while bypass rules keep LAN traffic, specific addresses, or selected apps on their original path. Strict routing can prevent unhandled bypass traffic, which helps keep paths consistent but may affect local development environments, virtual machines, or LAN services. If LAN devices become unreachable after enabling it, check private-address bypasses and direct rules first instead of disabling all routing.
MTU, Network Stacks, and UDP Issues
MTU is the size of packets an interface can carry. If it is too large, some network paths may not fragment packets correctly, causing small pages to load while large files or certain sites stall; if it is too small, packet overhead increases. Keep the client default unless there is clear evidence to change it. If MTU is suspected, compare different networks and check whether the issue appears only with large responses or specific protocols. Then lower it gradually, recording each value and result.
TUN network stacks differ in compatibility, performance, and system integration. Start with the client’s recommended default and switch only for a clear UDP, sleep/resume, or virtualization conflict. Restart TUN after changing the stack and confirm that the old virtual interface has been removed. On Android, VPN interception is provided by the system; v2rayNG and v2flyNG request the relevant permission when starting a connection. Another app using the same interception mechanism may conflict if both run simultaneously.
DNS Leak Misdiagnosis and Resolution Paths
After TUN is enabled, DNS requests may be handled by the client or may still leave through the system network interface, depending on the configuration. A common symptom is that domains fail while a known IP responds; check DNS first rather than the remote protocol. Another possibility is that DNS returns a result, but routing sends that result through the wrong outbound. Troubleshooting requires checking DNS, routing-match, and connection logs together, with corresponding timestamps.
If certain LAN domains depend on local DNS, keep a local resolution path for them while resolving public domains according to the intended policy. Do not force every scenario through one DNS server and then patch the result with large sets of static addresses. Local DNS reachability changes between corporate, home, and public networks, so mobile devices and laptops should specifically be tested after network changes.
If the entire system loses connectivity immediately after enabling TUN, disable TUN first and confirm that the default route has returned. Then inspect the log for permission, interface, and route-addition errors. Do not keep changing DNS and routing while the network is completely down; doing so makes the recovery path difficult to trace.
07 / maintenance
Routine Maintenance & Troubleshooting: Collect Evidence Layer by Layer
Build a Repeatable Maintenance Routine
Stable use depends on changes that can be rolled back. Perform client upgrades, core updates, subscription updates, routing-database updates, and system-network changes separately. Before each change, record the client type, selected configuration, local port, proxy mode, routing preset, and DNS policy. Validate against the same checklist afterward. Even when something breaks, this makes the before-and-after differences clear.
Update subscriptions according to how often their contents actually change; there is no need to refresh them repeatedly at every launch. Update GeoIP and GeoSite when routing shows clear classification errors or according to a maintenance schedule. Before upgrading the client, read its migration notice and confirm whether the configuration location or permission requirements have changed. After updating, verify the existing configuration first, then introduce new features. Combining an upgrade with a configuration redesign removes a clear rollback point.
Identify the Faulty Layer from the Logs
Read logs in chronological order. During startup, focus on configuration parsing, port listening, the core process, and the TUN interface. During connection setup, focus on DNS resolution, routing matches, outbound dialing, and the handshake. During operation, focus on timeouts, connection resets, and network changes. The first meaningful error is usually more valuable than repeated errors that follow, since later failures may simply result from the first break.
Configuration parsing errors often include a field path or JSON line and column location; fix syntax and field types first. Listener errors usually point to a port conflict or permission issue. Resolution errors point to the DNS path. A connection timeout means the request tried to leave the machine but the destination path did not complete in time. A handshake error requires checking the protocol, transport, and time. Do not share only the final log line; keep a continuous excerpt covering startup and one complete request.
| Symptom | Check First | Evidence to Collect |
|---|---|---|
| Core Will Not Start | Configuration syntax, port conflicts, runtime permissions | First error in the startup log |
| Browser Works, One App Does Not | Whether the app reads the system proxy | App proxy settings and inbound logs |
| Domain Fails, Known IP Responds | DNS server and resolution outbound | DNS log and routing match |
| LAN Becomes Unreachable After TUN Is Enabled | Private-address bypasses and strict routing | System routing table and direct rules |
| Configurations Disappear After a Subscription Update | Subscription response, filters, and groups | Update log and parsed item count |
Reproduce Minimally Instead of Resetting Everything at Once
A useful reproduction environment should be as simple as possible: select one known configuration, use the default local port, disable custom routing, keep TUN off, and use only the system proxy or a manual proxy for one app. If the minimal setup works, restore DNS, routing, TUN, and app rules one at a time. If it still fails, focus on configuration parameters, system time, ports, and the network path. This turns a complex problem into a finite sequence of checks.
“Reset to defaults” is useful for detecting configuration contamination, but record the current settings first. Clearing everything removes your comparison point and may delete a subscription that still works. A better approach is to create a separate test configuration or use the client’s backup and copy features. After testing, record confirmed changes in a maintenance log, including the item changed, reason, verification method, and rollback method. The record need not be long, but it must let you reconstruct the diagnosis next time.
Checks After Network Changes, Sleep, and System Updates
When a laptop switches networks, old DNS state, virtual-interface status, and route caches may remain temporarily. If connectivity fails after the switch, stop and restart the current configuration first; TUN users should also recreate the virtual interface. After sleep, the interface may still show the client as running even though the underlying network has changed. Judge the state from logs for a new request, not from the interface alone.
If problems begin after a system update, check firewall permissions, virtual-interface driver status, whether the system proxy was reset, and whether the client can still create network interfaces. On Android, stop and restart the connection after changing networks so the system can grant permission for the current path again. On every platform, avoid changing several configurations in succession before the problem is consistently reproduced; otherwise system-state changes and configuration differences become mixed together.
08 / advanced route
Advanced Config: From Interface Settings to Maintainable Rules
Stage One: Explain the Current Configuration
Advanced work starts not by adding fields, but by being able to explain the configuration you already have. Identify every inbound, the address and port it listens on, the default outbound, how direct and block are defined, the order of routing matches, and where DNS requests leave. Check each item against an exported configuration or runtime log, but do not edit temporary generated files directly. First map interface options to their final fields; only then can you understand why behavior changes after a client upgrade.
Create a traffic-path table for your own setup: application, entry method, inbound tag, matching rule, target outbound, and DNS path. Every column should be supported by the configuration or logs. If a value is based only on intuition, that part still needs verification. Once this is clear, move on to complex per-app, multi-entry, or multi-outbound scenarios without losing explainability as the rule set grows.
Stage Two: Organize Multiple Inbounds and Outbounds with Tags
Multiple inbounds are useful for separating apps or purposes. For example, one SOCKS inbound can serve a browser and another a development tool, with inboundTag directing them to different outbounds. Multiple outbounds can combine direct, block, and several remote connections. Name tags by responsibility, such as socks-browser, direct, and block, rather than using temporary numbers that are hard to remember. When renaming a tag, update every reference to it.
Multiple outbounds do not automatically require complex automatic selection. Start with clear static rules and confirm that each traffic class consistently reaches the intended outbound before considering failover or load-balancing policies. Automatic strategies depend on health checks, connection state, and core capabilities, and require more logs during failures. If basic routing is not stable, automation only makes the actual outbound harder to predict.
Stage Three: Maintain DNS as a Separate Subsystem
In a complex configuration, DNS is more than a server address. Define the query types, domain categories, resolution outbounds, caching behavior, and fallback conditions. LAN domains may need local DNS, public domains can follow the routing policy, and specific domains may use dedicated rules. Every split should serve a real need; do not enable every available option simply because it exists.
When validating DNS, first identify which layer initiated the request, then check whether the returned address is expected, and finally confirm which route carries that address. Looking only at the result can hide a difference in the network path; looking only at routing can make a bad address look like a routing problem. Change DNS separately from GeoIP and GeoSite updates so only one source of the decision changes at a time.
Stage Four: Establish Configuration Change and Rollback Rules
Long-term configurations should retain readable notes, but standard JSON does not support comments. Put explanations in a separate document, client notes, or a change log instead. For every edit, record the goal, old value, new value, verification result, and rollback steps. Routing rules especially need a record of why they exist; otherwise an obsolete rule can easily be mistaken for a requirement months later.
A configuration backup should include the subscription name, custom routing, DNS, listening ports, and TUN options, while its storage location should have restricted access. During restoration, do not import every old state at once. Restore the subscription and basic settings first, confirm that it runs, then restore routing and TUN. For cross-platform migration, move portable logic only; do not assume system proxy, virtual-interface, and permission settings can be copied directly.
Stage Five: Build a Fixed Verification Checklist
A complete checklist can include: the client starts normally; the core loads the configuration successfully; the local port is listening; the system proxy or TUN state is as expected; domain resolution works; private addresses stay direct; specified domains match the intended rules; connectivity recovers after a network change; and closing the client properly clears the system proxy and virtual interface. Every item should have a concrete observation method, not just “the network works.”
When a new problem appears, first place it in one layer—configuration, inbound, DNS, routing, outbound, or system interception—then use the corresponding chapter in this guide. For quick setup, return to the Getting Started Guide. To choose another package, open the client download page. For capability differences, see Client Comparison. If the issue involves configuration structure, port conflicts, or routing databases, continue with the linked topic articles.
Prepare the Client for Your Platform
Choose the package for v2rayN, v2rayNG, or v2flyNG, then follow this guide to complete the configuration in stages.