Core concepts: clients, cores, and proxy configuration
Understand the three layers before you start
v2rayN, v2rayNG, and v2flyNG are graphical clients. A client stores server profiles, manages subscriptions, generates core configurations, and provides controls for the system proxy, routing, and logs. Xray and V2Fly are proxy cores: they establish connections from the configuration, handle protocols and transports, and apply domain and IP routing. They are not interchangeable terms. Clicking “Start” in a client does not mean the graphical interface handles all network traffic itself; the client prepares the configuration and invokes the core. When troubleshooting, first determine whether the problem is in interface management, core startup, the remote configuration, or the application’s failure to use the local proxy.
The third layer is proxy configuration. It defines the server address, port, user identifier, protocol, transport, TLS, routing, DNS, and other parameters. The client is only a management tool for this data; whether a configuration works depends on the fields matching one another. A subscription is one way to distribute configurations in bulk. It is neither a client nor a core. A successful subscription update only means that the client fetched and parsed the content; it does not prove that every profile can establish a connection. Conversely, a failed update does not mean the local core is damaged. The subscription URL, network path, or response format may be the actual problem.
Client management layer
Imports, selects, edits, tests, and saves configurations while controlling the system proxy, TUN, and core process.
Core execution layer
Reads the configuration generated by the client, listens on local ports, handles protocols, evaluates routes, and forwards connections.
Configuration data layer
Contains remote connection parameters and local behavior rules. Every required field must match; the protocol name alone is not enough.
Application access layer
Browsers, terminals, and other programs must connect through the system proxy, their own proxy settings, or TUN.
The path of a request
Take a browser loading a web page as an example. The usual path is: the browser reads the system proxy settings and sends the request to v2rayN’s local HTTP or SOCKS listening port; the core uses routing rules to choose a direct or proxied outbound; if it chooses the proxy outbound, it establishes a remote connection from the server configuration. If any link breaks, the visible symptom may simply be “the page won’t open.” That is why repeatedly changing profiles should not be the first response. First confirm that a local listener exists, then confirm that the application sends traffic to it, then check whether the core received the request, and only afterward inspect remote parameters and network conditions.
The system proxy and split routing operate at different layers. The system proxy answers “which applications that follow system settings send requests to the client?” Routing answers “which outbound does the core use after receiving a request?” If a terminal program does not read the system proxy, changing routing rules ten times will make no difference because the request never entered the core. Likewise, enabling TUN only broadens the access scope; it does not automatically fix an incorrect server address, TLS parameter, or user identifier. Keeping this boundary clear prevents later settings from interfering with one another.
Build a rollback-friendly learning environment
For the first setup, keep one server profile from a known source, use the default routing, avoid enabling TUN immediately, and leave DNS unchanged. First make the browser complete a repeatable test through the system proxy, then add features one at a time. After each stage, record the key client options, local ports, and current profile name. If a later routing rule is wrong, you can return to the baseline of one profile, default routing, and the system proxy instead of reinstalling the client. Reinstallation usually only clears interface files or local data; it cannot automatically correct subscription content, remote parameters, or an application’s own proxy settings.
Choose a client by platform and core requirements
Use v2rayN first on desktop platforms
v2rayN is the primary choice for Windows, macOS, and Linux. It provides a desktop GUI for managing subscriptions, profiles, the system proxy, routing, DNS, TUN, and logs. The Windows download page offers both a desktop build and the classic WPF build. The desktop build uses a cross-platform interface and suits users who want a similar workflow across desktop systems; the classic WPF build uses native Windows desktop technology and suits users familiar with the traditional v2rayN layout. Both are client choices, not protocol or core types.
When choosing a desktop package, also check the processor architecture and package format. Most Windows desktops use x64. On macOS, first determine whether the device has Apple Silicon or an Intel processor. On Linux, choose deb or rpm according to the distribution in addition to checking x64 or arm64. An architecture mismatch usually appears as an installer that will not start, an unsupported format warning, or a program that exits immediately. This is a client runtime issue, unrelated to the subscription URL or server configuration. Return to the client download page and confirm the platform entry.
Choose between v2rayNG and v2flyNG on Android
v2rayNG is the recommended Android choice. It primarily uses the Xray core and suits common protocol, routing, and per-app proxy scenarios. v2flyNG uses the V2Fly core and is an alternative when V2Fly behavior or an existing V2Fly-based workflow is specifically required. The two apps do not have identical interfaces or setting locations, and whether the same subscription can be imported depends on its fields and the core’s capabilities. Similar names do not guarantee that every option maps directly.
Android packages usually come in arm64 and universal variants. Most newer mainstream phones use arm64; choose the universal build if the architecture is unknown. After installation, Android displays an authorization prompt the first time the app starts a VPN connection. This permission creates the local virtual network interface required to handle traffic. If another VPN-style connection is active, end it first because the system normally allows only one such interface at a time. Background operation may also be affected by battery-saving policies; address that only after the connection baseline is working.
| Platform | Preferred client | Selection focus | First check |
|---|---|---|---|
| Windows | v2rayN | Desktop build or classic WPF build, x64 architecture | Core startup and local ports |
| macOS | v2rayN | Apple Silicon or Intel | System security approval and proxy settings |
| Android | v2rayNG | arm64 or universal build, VPN permission | Other VPN conflicts and battery-saving policies |
| Linux | v2rayN | x64 or arm64, deb or rpm | Desktop session and system proxy support |
Do not substitute feature count for actual requirements
Choose a client by answering three questions: What platform is the device on? What core capabilities does the existing configuration require? How will the application connect? For Windows browsers and ordinary desktop programs, v2rayN with the system proxy is usually enough. If Android needs per-app proxying, define the included or excluded apps in v2rayNG. Only when a program ignores the system proxy should you evaluate its own proxy settings or TUN. Cover the requirement with the smallest workable setup; maintenance is much easier than enabling every advanced feature from the start.
When migrating from an old client, re-import the subscription or a standard share configuration instead of copying the entire program directory. The old directory may contain outdated routing files, port settings, logs, and interface state, bringing historical problems along with it. After migration, select one profile, confirm the local listener, and restore routing rules one group at a time. Server profiles are sensitive connection data and should be stored only on controlled devices and in reliable backup locations. Mask subscription URLs, user identifiers, and authentication data in screenshots and troubleshooting records.
If you are still unsure, read the client comparison. Confirm the platform and client before moving to installation so that a startup failure caused by the wrong architecture or package format is not mistaken for a subscription or network problem.
Installation and first launch: confirm the core and listening ports first
Windows installation and directory boundaries
After obtaining a v2rayN package that matches the Windows system architecture, install or extract it according to the package type shown on the download page. If you use an archive-based build, place it in a fixed directory where the current account has read and write access. Do not run it long-term from an archive preview window or a temporary downloads folder. The client needs to save configurations, update components, and write logs; insufficient permissions can leave the interface working while configurations fail to persist, the core cannot shut down cleanly, or updated files go missing.
After the first launch, do not import a large number of subscriptions yet. Open the client’s settings or log area and confirm that the core process can be invoked. Record the local HTTP and SOCKS listening addresses. A common listening address is 127.0.0.1, which allows access only from the local machine; the port is determined by the client and must not be treated as the fixed value shown in an example. If a security tool asks for network access, decide according to the intended scope. A local loopback proxy does not need to be exposed to the public network.
First-run permissions on macOS, Linux, and Android
When you first open a downloaded app on macOS, the system may ask you to confirm its source or grant network-configuration permissions. After granting access, check whether the system-proxy control in the menu bar or client can write to the current network service. After switching between Wi-Fi, Ethernet, or another network service, verify the proxy state again because each service can store separate settings. Linux desktop environments do not offer identical system-proxy support. Some applications read desktop proxy settings, while some command-line programs use only their own parameters or environment variables. A running client does not mean every program is connected.
Android requires confirmation of the system VPN permission on the first connection. After authorization, the VPN symbol in the status bar only shows that the virtual interface exists; it does not prove that the remote profile works. Select one profile, look for a clear client error, and then run a basic browser test. If the app disconnects soon after entering the background, check battery optimization, background-activity permissions, and task-cleanup policies. If only some apps fail, inspect the per-app proxy scope instead of reinstalling repeatedly.
- Confirm that the client itself starts reliably Close duplicate processes with the same name, then start one instance. If the interface disappears immediately, check the system architecture, runtime permissions, and client logs before handling subscriptions.
- Confirm that the core is invoked correctly Look in the logs for configuration parsing, listener failures, or permission issues. At this stage, evaluate only the local execution chain; do not use web access as a substitute for checking the core.
- Confirm that the local port is listening Record the actual port for the HTTP, SOCKS, or mixed listener. Browsers, terminals, and system proxy settings must all use the matching port type.
- Save an initial settings record Record the client type, selected core, listening address, port, and whether the system proxy is enabled as a baseline for troubleshooting.
On Windows, check whether the specified port is listening. The example port is 10809:
netstat -ano | findstr :10809
If the command returns nothing, the port is not currently listening or the actual port is not the example value. Return to the client and check its listener settings. If another process is using the port, use the PID in the last column to locate it in Task Manager. Starting v2rayN twice, running another local proxy, or using development tools can all cause conflicts. See Troubleshooting a v2rayN local port conflict for detailed steps.
Verify the shortest path on the first connection
After completing the local checks, import one profile and select it as active. Keep the client’s default routing and DNS, and do not enable complex rules. Turn on the system proxy and use a browser known to read it to open an ordinary HTTPS page while watching the logs for the corresponding domain request. If the browser sends a request but the connection fails, investigate the remote configuration or network layer. If the logs show no request at all, check whether the browser uses its own proxy, whether the system proxy was written successfully, and whether the port matches.
After testing, deliberately test “Clear system proxy.” Restore the system proxy before closing the client so the operating system does not continue pointing to a stopped local port. If all web pages fail after an abnormal exit, first check for and clear a leftover system proxy instead of changing DNS. The goal of installation is not to enable every feature, but to establish a local baseline that starts, listens, accepts traffic, and shuts down cleanly.
Subscriptions and configuration management: separate retrieval, parsing, and connectivity
A subscription update has three separate outcomes
A subscription update passes through at least three stages: accessing the URL, parsing the content, and writing configurations. The client first requests the subscription URL. After receiving a response, it checks the format and parses the profiles, then writes valid entries to the relevant group. The list updates only when all three stages succeed. If the network request fails, check whether the URL is reachable from the current network, whether the system clock is correct, and whether the client uses a suitable network path for subscription updates. If parsing fails, inspect whether the response uses a format supported by the client instead of repeatedly changing local ports.
A subscription URL usually grants access to configuration data and should be treated as sensitive. Do not include the full URL in public screenshots, log attachments, or browser-synced notes. Give each subscription a clear group name, such as one based on its purpose or source, rather than “Subscription 1” or “Subscription 2.” The group name does not change connection behavior, but it helps identify which update affected which profiles. When multiple sources share one group, duplicate names or differing fields make it difficult to identify the source of a problem.
Post-import checks go beyond “it appears in the list”
Once a profile is listed, check at least its protocol, server address, port, transport, TLS state, and server name. Authentication data such as the user identifier may be hidden in the normal interface, but its presence and format must still be correct. Protocol names such as VLESS and VMess describe only part of a profile. The transport—WebSocket, gRPC, or TCP—and fields such as TLS, SNI, path, or service name must also match. Changing only the protocol field cannot fix mismatched fields elsewhere.
Bulk-test results are useful only as filtering clues. A failed test may be caused by the current network, remote status, test target, or DNS; a successful test does not mean every application is connected correctly. A more reliable method is to select one profile, keep default routing, make a real browser request, and interpret it with the core logs. Rotating through multiple profiles for the same issue makes the logs and system proxy state change constantly, making cause and effect harder to establish.
- Add a subscription and name its group Add the URL through the client’s subscription manager and make sure it has no leading, trailing, or embedded spaces or line breaks. After saving, update only the newly added group so the result is easy to identify.
- Review the update message and group changes Distinguish a request failure, a parsing failure, and a successful write that produced no valid entries. Each stage requires different checks; do not attribute them all to the core.
- Inspect the fields of one profile Confirm that the protocol, address, port, transport, and TLS fields are complete, then set the profile active and start the core.
- Keep the latest working fallback Export or back up the current configuration database before updating. If the source changes, you can quickly determine whether the issue came from the update or from the local environment.
Check each stage when an update fails
If the client cannot connect to the subscription URL, first confirm that the address is complete and check whether the system proxy points to a local port that is no longer running. A browser being able to open the URL does not necessarily mean the client’s subscription request follows the same path; they may use different proxy settings. If the response is a login page, error page, or ordinary text, the client will usually report a format error. Verify the subscription source instead of importing web-page content as a share configuration.
If the update succeeds but the list is empty, check whether group settings filter certain profiles and whether the response contains configurations recognized by the current client. If existing entries disappear after an update, do not refresh repeatedly. Check whether the subscription replaces the group, then restore the profiles that must be kept from a backup. See subscription update FAQs for fuller classification steps, or the quick-start subscription steps for a streamlined first import.
Manual configuration is useful for precise verification
When there is only one profile or you need to verify specific fields, use the client’s manual-add function. Check every field from top to bottom instead of guessing from similar names. The server name used for the TLS handshake must match the configuration requirements; transport paths, Host values, service names, and other fields each have their own role. For certificate or TLS handshake errors, first check the system clock, certificate validity, domain matching, and SNI. See Troubleshooting TLS handshakes and certificate errors for the underlying principles. Disabling certificate verification should not be a routine fix.
After completing the subscription stage, you should be able to answer four questions: Which group supplied the profile? Which profile is active? What kind of configuration is the core using? What is the local listening port? Only with these details clear can system-proxy and application-access testing proceed on a reliable basis.
Proxy modes and application access scope
The system proxy covers only applications that read system settings
In v2rayN, “Automatically configure system proxy” usually points the operating system’s proxy address to the client’s local listening port. Browsers and some desktop applications read this setting and can connect without separate configuration. Other programs have independent proxy settings or ignore the system proxy entirely, including some terminal commands, development tools, game platforms, and applications with their own network stack. If the system proxy is enabled but one program still connects directly, that does not automatically mean v2rayN or the core has failed. First check how that program connects.
“Clear system proxy” removes the system setting written by the client. Clear the old proxy before stopping the client, changing the local port, or switching to another network tool. If the system still points to a port under 127.0.0.1 but no process is listening there, applications that follow the system proxy will all fail to connect. This often happens after an abnormal exit and can look like the entire network is down; in reality, clearing the leftover system proxy is usually enough.
| Access method | Suitable for | What to check | Common boundary |
|---|---|---|---|
| System proxy | Browsers and desktop apps that read system settings | System address and port must match the client listener | Does not cover every terminal or independent network stack |
| Application proxy | Terminals, development tools, and programs supporting manual proxy settings | HTTP or SOCKS type, authentication, and port | Must be maintained separately for each application |
| TUN | Programs that are inconvenient to configure one by one | Virtual interface, routing, DNS, and permissions | May conflict with other VPNs or virtual network adapters |
HTTP and SOCKS ports are not interchangeable
A local HTTP proxy suits applications that explicitly support HTTP proxies; a SOCKS proxy forwards connections through the SOCKS protocol. The client may provide separate ports or a mixed port compatible with multiple access methods. The application must use the matching listener type: putting a SOCKS port into a field that accepts only HTTP proxies usually causes a protocol handshake error or a reset connection. The address is generally 127.0.0.1, meaning the local client. Do not replace the loopback address with an arbitrary network-interface address unless you have explicitly configured LAN listening and access control.
A browser can use the system proxy for baseline testing. If it has a proxy extension installed, check whether the extension follows the system or uses a custom mode. A fixed port in the extension can override the system setting, so the browser may keep using an old listener after the client port changes. Private windows and separate browser profiles may also have independent rules. If the browser works but a terminal does not, troubleshoot them separately. See Checking proxy scope for browsers and terminals for specific steps.
Terminal programs usually require explicit configuration
Many command-line tools read environment variables such as HTTP_PROXY, HTTPS_PROXY, and ALL_PROXY, but support varies by tool. Environment variables can apply to a process, a terminal session, or persistent system settings. For troubleshooting, set them temporarily in the current terminal and close the window after testing so an obsolete port is not left in the global environment. The examples below assume that v2rayN’s HTTP listening port is actually 10809; replace it with the port shown in the client.
Windows Command Prompt, current session:
set HTTP_PROXY=http://127.0.0.1:10809
set HTTPS_PROXY=http://127.0.0.1:10809
curl https://example.com
PowerShell, current session:
$env:HTTP_PROXY="http://127.0.0.1:10809"
$env:HTTPS_PROXY="http://127.0.0.1:10809"
curl.exe https://example.com
If the core logs still show no request after running the command, check whether the tool reads these variables, whether the variable names are correct, and whether the address and port point to the HTTP listener. If the logs show a request but the connection fails, investigate routing, DNS, or the remote configuration. Do not infer the layer solely from a “timeout” in the terminal output; an unlistened local port, an unreachable remote server, and failed domain resolution can all look similar.
Verify proxy scope, not just the exit result
Reliable verification checks three signals together: the application actually uses the intended proxy setting; the client logs receive the application’s domain or connection; and the routing result matches expectations. Viewing a single exit page cannot prove that every application follows the same path or that DNS queries receive the intended handling. Test a browser, a terminal, and one target application separately, generating only a few identifiable requests each time, then use the logs to confirm whether they entered the core.
At the end of this stage, you should know which applications follow the system proxy, which use their own settings, and which still cannot connect. Consider TUN only if the third category genuinely exists and cannot be configured individually. If the system proxy already works reliably for the environment, moving directly to split routing is usually simpler.
Split routing: choose an outbound after the request enters the core
Routing determines the outbound
Routing handles only traffic that has already entered the core. Based on conditions such as domains, IPs, ports, network types, and inbound tags, it sends requests to a proxy, direct connection, block, or another outbound. A common goal is to send LAN traffic and clearly internal addresses direct while using a proxy for everything else; domain lists can provide finer control. Whatever the strategy, define the default behavior first, then add narrowly scoped exceptions. If you write only a few exceptions without understanding the final fallback outbound, unmatched requests may take an unexpected path.
Rules are usually matched in order, and a broad condition near the top can hide a precise condition below it. For example, if a rule proxying all TCP and UDP traffic comes first, a later rule for direct private-address traffic will never match. In general, put precise rules that must be direct or handled separately first, broader categories later, and a fallback last. After editing, validate each rule with a clear domain instead of importing a long rule set and testing only one page.
Domain rules, IP rules, and resolution strategy
Domain rules are most straightforward while the core still has the original target domain and can match a full domain, suffix, or predefined category. IP rules depend on the destination IP. When a request starts as a domain, whether routing performs an additional resolution depends on settings such as domainStrategy. An overly aggressive resolution strategy can add DNS queries and change the matching path; refusing to resolve may prevent rules written only for IPs from handling domain requests. Choose the strategy based on the conditions your rules actually use rather than treating one strategy name as universally optimal.
Direct connections to private addresses are commonly used for the local machine, LAN devices, and internal services, but the actual network still matters. Corporate networks, virtual machines, containers, and development environments may use different private ranges. Multiple virtual adapters can also affect the system route. If a domain resolves to a private address, check whether the DNS result came from the current network. When a domain fails but entering the internal IP works, compare the resolution result and matched route instead of changing only the proxy outbound.
An Xray routing fragment for explaining the rule structure; outbound tags must match the outbound tags in the complete configuration:
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": [
"domain:intranet.example.com"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
This configuration means that specified internal domains use a direct connection, private IPs use a direct connection, and all other TCP and UDP traffic goes to the outbound named proxy. It is only the routing section of a complete configuration and cannot run as the client’s full configuration by itself. If the client manages routing through a GUI, express the same logic in its rule editor instead of overwriting other generated fields. If the outbound tag does not exist, the core reports a configuration error. Missing rule data files or unsupported names can also produce messages during startup or matching.
| Condition | Best suited for | What to check |
|---|---|---|
| domain | Full domains, suffixes, and domain categories | Whether the original domain is still available for matching |
| ip | Private ranges, fixed addresses, and IP categories | Resolution strategy and actual resolution results |
| port | Explicit port ranges | Destination ports, not local listening ports |
| network | TCP, UDP, or both | Placement of broad-scope rules |
Expand gradually from a minimal rule set
When building routing, keep one direct rule for private addresses and one clear fallback. Confirm that the browser, terminal, and LAN services behave as expected. Then add one group of domain rules at a time, recording the target and maintenance source for each group. Name rules by purpose, such as “LAN direct” or “Development services direct,” rather than “Rule 1.” If a rule causes a problem, disable that group temporarily and return to the previous stable state.
Record DNS and routing separately. Routing chooses the outbound; DNS obtains an address. They affect each other but are not the same setting. If only domains fail, compare resolution results first. If IP connections also fail, inspect the outbound and remote connection. If the request never appears in the logs, return to the application access layer. Separating these symptoms prevents endless DNS changes in the routing page while another resolver is configured at the system level.
Acceptance testing after split routing
Test at least three target types separately: a LAN address, a domain that must use a direct connection, and an ordinary domain that uses the proxy outbound. For each target, record the application access method, resolution result, matched rule, and final outbound. If LAN access breaks when the proxy is enabled, first check whether a broader proxy rule matched the private address earlier. If a domain sometimes takes different paths, check whether it resolves to multiple addresses and whether the rule applies by domain or by IP.
Consider TUN only after routing is stable. Once the access scope expands, you can still use the validated rules to explain the outbound. If routing is unclear during the system-proxy stage, enabling TUN immediately brings more programs and system traffic into the same unverified rules and makes the failure scope larger.
TUN mode: handle traffic from applications that ignore the system proxy
TUN changes the traffic entry point
TUN receives system traffic through a virtual network interface, giving applications that do not support HTTP or SOCKS proxy settings a way to enter the core. It solves application access scope, not protocol selection, and it does not make an incorrect remote configuration work automatically. Once enabled, system routes, the virtual adapter, DNS, and the core’s inbound all participate, adding several possible failure points beyond the system proxy. Move to this stage only after the basic setup has been verified through the system proxy and there is a real application that cannot be configured separately.
On desktop systems, creating a virtual interface or changing routes may require additional permissions. With insufficient permissions, the client may show that the toggle was used while the logs report failures creating the interface, writing routes, or accessing a driver. Android’s VPN access uses the system’s virtual-network mechanism, but you still need to check authorization, other VPN conflicts, per-app scope, and background restrictions. Platform implementations differ; do not copy driver or permission procedures from one platform to another.
Fix the baseline before enabling TUN
- The active profile has passed browser testing through the system proxy.
- The local listener and core logs are normal, with no persistent configuration errors.
- Routing has at least passed private-address direct access and default-outbound tests.
- No other VPN or virtual-network takeover tool is running at the same time.
- The DNS, system proxy, and client settings from before enablement have been recorded.
Once these conditions are met, remove duplicate traffic-capture methods first. If TUN will handle most traffic, adjust the system proxy as directed by the client so the same request does not pass through unnecessary duplicate entry points. After enabling TUN, test a basic web page, then an application that previously ignored the system proxy, and finally a LAN service. At every step, check the logs for the request and confirm the routing choice. Do not add new DNS settings, complex rules, and multiple bypass lists during the first enablement.
- Close potentially conflicting virtual network connections End other VPN sessions and similar traffic-capture programs while keeping the physical network active. Do not blindly remove virtual-machine or container networks; record their ranges and routes.
- Enable TUN with the required permissions Use the client logs to confirm that the virtual interface was created and routes were written. The toggle color alone does not prove that the system-level setup completed.
- Verify DNS and ordinary TCP requests Test domain resolution first, then test a browser connection. If an IP works but the domain fails, focus on the DNS path used by TUN.
- Test the target application and LAN Confirm that the previously disconnected program appears in the logs, while printers, router administration pages, and internal services still connect directly according to the rules.
How to isolate common conflicts
If the network goes completely offline after enabling TUN, first check whether the virtual interface and default route were created, then check whether the core is still running. If disabling TUN immediately restores access, the issue is in the TUN entry point, routing, or DNS; reinstalling the client is unnecessary. If only domains fail while direct IP access works, check DNS reachability, the intended query outbound, and the resolution result. If only LAN access fails, inspect private-address rules and system route priority, especially when a virtual adapter and the physical LAN use overlapping ranges.
If an application still does not enter the proxy, check whether per-app rules exclude it, whether it uses a separate network interface, or whether its traffic falls outside the current TUN implementation. On Android, also confirm whether the app is configured to “proxy only selected apps” or “bypass selected apps”; these modes have opposite meanings. See Android permissions, battery settings, and per-app proxying for related background and per-app issues.
DNS is central to TUN troubleshooting
As TUN expands the access scope, DNS requests from system services and more applications may also enter the processing chain. You need to know who receives the query, which server is used, whether the result affects routing, and whether the returned address is reachable through the current outbound. If the system DNS, client DNS, and encrypted DNS inside an application are all configured, the actual path may differ from expectations. Temporarily reduce the layers: validate with one clearly defined client DNS setup, then restore application-specific settings as needed.
If the logs show successful domain resolution followed by a failed connection, inspect the resolved address and routing outbound. If there is no query record, the application may be using a cache or its own resolver. Flushing the cache can help verify the cause, but it is not a long-term solution. The goal is for the same domain to produce an explainable and repeatable resolution and routing result under the same network conditions.
Restore system state when leaving TUN
After disabling TUN, confirm that the virtual interface and temporary routes were removed, and check that the system proxy still points to a running client. If an abnormal exit left routes behind, restart the client and disable TUN normally before using system network tools to inspect the routes. Do not reset every network setting at once, or you may lose existing static addresses, corporate-network settings, or virtual-machine configuration. Keep the pre-enable record and compare changes one by one.
The completion standard for TUN is not that the toggle stays on. Target applications must enter the core, LAN access must remain available, the DNS path must be clear, and the system must recover after TUN is disabled. If the system proxy already covers all requirements, continuing with the simpler access method is perfectly reasonable.
Maintenance and troubleshooting: start with the latest change
Focus maintenance on configuration, state, and change records
Routine maintenance does not require frequent reinstallation. More important is keeping records of subscription groups, manual profiles, routing rules, DNS settings, and local ports, and creating a backup before updating the client or changing rules. Backups may contain subscription URLs and connection credentials, so store them in a controlled location and do not transmit them publicly as ordinary text. When restoring, import and validate the smallest configuration first, then restore larger rule sets so you can distinguish a backup problem from an environment problem.
After updating the client, first confirm that interface settings were preserved, the core starts, and the local port has not changed, then test the system proxy. Do not combine an update, subscription refresh, routing replacement, and TUN change in one operation. Change one category of variable at a time so you can roll back. When migrating devices, record the client type, architecture, core choice, subscription groups, listening port, routing strategy, and special application proxy settings. This is easier to control than copying the entire old directory.
Create a consistent troubleshooting taxonomy
| Symptom | Check first | Next step |
|---|---|---|
| Client will not start | Architecture, directory permissions, duplicate processes | Review the client’s own logs |
| Core startup fails | Configuration parsing, local port conflict | Find the first clear error |
| No browser requests in the logs | System proxy, browser-specific settings | Verify the address and port type |
| Requests appear but connections fail | Routing, DNS, remote configuration | Check protocol and transport fields |
| Only some applications fail | Application access method, per-app scope | Evaluate manual proxy settings or TUN |
When troubleshooting, first record when it happened, what changed recently, and the affected scope. If every application following the system proxy fails at once, check the client process, local listener, and system proxy. If only one application fails, inspect its independent settings first. If the same profile behaves differently on different networks, focus on DNS, the network path, and the system clock. Scope is often more informative than the error text because many “connection timeout” messages do not identify which layer timed out.
Read logs from the first meaningful error
A client and its core may produce a long chain of messages after one failure. Start at the time of the current launch or action and look for the earliest configuration-parsing, listener, DNS, TLS, or connection error. Later retry lines are usually consequences. Before sharing logs, remove subscription URLs, user identifiers, server addresses, and other sensitive fields, leaving only the error type, sequence of events, and necessary context.
If the core says an address is already in use, locate the process occupying the port first. If it reports an invalid configuration field, return to the latest edit or subscription update and check whether the imported field is unsupported by the current core. For TLS certificate errors, synchronize the system clock first, then verify the server name and certificate domain. For DNS timeouts, confirm the DNS path and server reachability instead of immediately blaming the server configuration.
Ports, the system proxy, and abnormal exits
When a local port is occupied, determine first whether the same client was started twice, then check other programs. Changing the port can bypass the conflict but affects every manually connected application. Update browser extensions, terminal variables, development tools, and LAN device settings afterward. If the port is held by an obsolete process, ending that process normally is usually easier to maintain than continually changing ports.
After an abnormal client exit, the system proxy may remain configured. The browser then continues sending requests to a nonexistent local port. Reopen v2rayN and use “Clear system proxy,” or restore the setting in the operating system’s network preferences. Do not delete network adapters just because every page fails. With TUN, also confirm that the virtual interface and routes were removed; a leftover system proxy and leftover TUN routes are separate problems and require separate checks.
Periodic checks for subscriptions, time, and certificates
There is no need to refresh a subscription repeatedly every time the client starts. Set a schedule that matches the actual update need and keep the latest working profile. If many entries change at once after a refresh, validate one entry first instead of immediately deleting the old records. Keep the system clock synchronized automatically because TLS certificate validation depends on accurate time; clock drift can look like a certificate that is not yet valid or has expired. The server name, SNI, and certificate domain must also match; repeated connection attempts cannot fix incorrect fields.
During long-term use, also monitor disk space and log growth. Logs help with troubleshooting, but keeping them forever makes them harder to search. Use the client’s supported cleanup method for old logs and do not directly delete an unfamiliar configuration database. Read the change notice before an update and verify the shortest path afterward. Find more common symptoms in FAQs, organized under “Installation and configuration” and “Troubleshooting.”
Keep reusable troubleshooting records
A useful record should include the platform, client, core, access method, active profile type, listening port, whether routing and TUN are enabled, the time of the error, the first meaningful log entry, and the steps already verified. Do not write only “it doesn’t work.” These details quickly narrow the issue to the client, core, configuration, or application scope and prevent starting over next time. After resolving the problem, document the change that actually worked and remove temporary settings that had no effect so they do not become the source of the next failure.
Advanced configuration roadmap: from working to explainable
Advanced does not mean turning on more switches
After the basics are complete, the goal of advanced configuration is to make behavior explainable, testable, and reversible—not to enable more features at once. A mature setup should answer: which applications use the system proxy, which use their own settings or TUN; who handles DNS queries; which route matches each domain and IP category; what protocol, transport, and TLS parameters the active profile uses; and which settings must be updated after a client update or port change. Being able to answer these questions matters more than the number of enabled options.
A useful learning path has four layers: observation, rules, protocols, and automation. First learn to read client and core logs and trace a request from the application to the outbound. Then maintain a small set of routing and DNS rules. Next understand how protocol, transport, and TLS fields work together. Only afterward consider backups, migration, and repeatable verification. Each layer depends on a stable baseline from the previous one.
Understand protocol, transport, and TLS separately
VLESS and VMess are proxy protocols; TCP, WebSocket, and gRPC describe the transport; TLS establishes an encrypted connection and verifies the peer. Whether a profile connects depends on these layers matching together. Seeing the same protocol does not imply the same transport path, service name, server name, or security parameters. When learning a new profile, list the key fields by protocol, transport, and TLS layer, then use core logs to identify the layer where the failure occurs.
The TLS handshake takes place while a protected connection is being established. An incorrect system clock, an invalid certificate period, or a mismatch between the server name and certificate domain can all cause the handshake to fail. SNI indicates the target server name during the connection and should not be filled with an unrelated domain. A path or service name in the transport layer is determined by the remote service configuration and must not be guessed. Advanced troubleshooting is about checking each layer, not trying random combinations.
Create a routing and DNS test checklist
After adding routing rules, maintain a fixed set of test targets: a LAN address, an internal domain, an ordinary direct target, a proxied target, and an application that requires UDP. Test them in the same order after every rule change and record the matched outbound. DNS tests should also record the resolver, returned addresses, and whether the query used the intended entry point. Fixed samples help determine whether a change came from the rules or from the target site, cache, or current network.
When rule files or category data are updated, validate a small number of targets first. Category definitions may change their coverage, so review the placement of broad rules especially carefully. Custom rules should record why and when they were created; there is no need to invent performance figures. If a rule has no clear long-term purpose, consider removing it to reduce future conflicts. A small, explainable rule set is usually more reliable than a large set from unknown sources.
Treat different devices as separate environments
Desktop systems and Android can use the same subscription source, but their system proxies, VPN interfaces, background policies, and per-app capabilities differ. Do not assume that an access method verified on Windows can be copied unchanged to Android, and do not attribute an Android VPN-permission problem to the subscription. When troubleshooting across devices, first confirm that both use the same profile, that the system clocks are correct, and that network conditions are comparable; then compare core and field support.
If several desktop devices use v2rayN, standardize subscription-group names and routing targets, but record listening ports, installation paths, and system proxy settings per device. macOS and Linux implement system proxy support differently, and command-line tools may use their own environment variables. Share the configuration logic, not the operating-system state. Migration documentation should describe the intended behavior while retaining platform-specific checks.
Design three stable configuration profiles
Daily setups can be divided into three profiles. The baseline profile contains one active profile, default routing, and the system proxy for validating the core and browser. The split-routing profile adds tested direct rules and a defined DNS path for everyday desktop use. The extended profile enables TUN on top of split routing for applications that ignore the system proxy. Each profile should be independently reversible. If something breaks, step down to the baseline instead of deleting every configuration.
Document the differences between profiles, including system proxy state, TUN state, DNS settings, routing-rule groups, and application-specific proxies. After switching, validate with the same set of test targets. This quickly shows whether a failure came from a remote-profile change or a local advanced feature. If the baseline also fails, there is no reason to adjust TUN. If the baseline works but the extended profile fails, the issue is narrowed to the virtual interface, routing, or DNS.
| Profile | Included settings | Primary purpose | Acceptance focus |
|---|---|---|---|
| Baseline | One profile, default routing, system proxy | Establish the shortest working path | Core, listener, browser requests |
| Split routing | Baseline plus routing and defined DNS | Separate direct and proxy outbounds | Rule matches and resolution results |
| Extended | Split routing plus TUN | Cover more application traffic | Virtual interface, LAN access, and clean exit |
A sequence for continued learning
Use the concept quick reference to fill in terminology for protocols, cores, subscriptions, the system proxy, and routing. Then use the client comparison to understand platform differences. For a specific issue, use FAQs to identify the category before reading the related article. For the relationship between Project V, V2Fly, Xray, and the three clients, see the open-source ecosystem and client selection guide. The resources should form a sequence of “concepts—operation—verification—troubleshooting,” rather than a collection of isolated parameters.
At this stage, configuration work has shifted from “make one connection succeed” to “make behavior predictable over time.” Keep a minimal baseline, limit simultaneous changes, record application access scope, verify evidence for every route match, and maintain controlled backups of subscriptions and sensitive configuration. This approach applies to v2rayN, v2rayNG, and v2flyNG and helps distinguish client-interface differences, core behavior, and operating-system networking.