TROUBLESHOOTING MANUAL

V2Ray Troubleshooting: Check the full connection path by symptom

Check each layer in order: the client process, local listening port, system proxy, DNS, routing rules, and the remote handshake. Change one condition at a time and confirm the result with logs or commands, so changing the node, mode, and network together does not erase the evidence.

App System proxy Local port Routing / DNS Node handshake Destination site

If the client is not yet installed, the subscription has not been imported, or the first connection has not been completed, start with the Quick Start Guide to build a working baseline. This page is not a repeat of the installation steps; it is a reference for diagnosing problems after the connection has been configured. Visit the Client Downloads if you need a different installer, and see the Frequently Asked Questions for quick answers.

01 / LOCAL CHAIN

Connected but no internet: check the local path first

Break “no internet access” into testable symptoms first

A client showing “Connected” usually means only that the configuration has been handed to the core. It does not mean that browsers, terminals, and other apps can reach their destinations through the node. First disable the system proxy or stop the current configuration and check whether the device can reach a normally reliable site over the direct connection. If direct access also fails, investigate the router, Wi-Fi, network adapter, or ISP connection first. If direct access works but everything fails when the client is enabled, focus on the local proxy, routing rules, or remote node.

Next, test the browser and command line separately. If the browser works but the terminal fails, the two apps probably read proxy settings differently. If both fail, continue with the local port and core logs. Also distinguish between “no domain works” and “only a few sites fail”: the former points more often to a broken local proxy or node path, while the latter is commonly related to routing, DNS, or the destination site’s network policy. An accurate symptom report is more useful than repeatedly clicking Connect.

Confirm the core process and local listening port

v2rayN, v2rayNG, and v2flyNG must start the corresponding core and create a local entry point. On desktop, check the client status area to see whether the current configuration is running, then verify the HTTP, SOCKS, or mixed proxy port in Settings. Do not guess based on port numbers from a tutorial: the port may have been changed or startup may have failed because another program is using it. On Windows, use the following command to check the port. Replace the port number with the actual value shown by the client:

netstat -ano | findstr LISTENING
Get-NetTCPConnection -State Listen | Sort-Object LocalPort

If the port is not listed, return to the client log and look for messages such as “address already in use,” “failed to listen,” or configuration-load errors. When a port is occupied, close the program using it or choose an unused port in the client settings, then fully stop and restart the core. Changing the setting without restarting the core may leave the old process on the original port while the system proxy points to the new one, creating a connected-looking state with no actual traffic.

Check the system proxy target and routing mode

When the system proxy is enabled, it should point to the loopback address and the port currently listening on the device. On Windows, the usual address is 127.0.0.1; do not accidentally enter the address of a local network adapter. If the client offers options such as “automatic configuration script,” “global proxy,” and “clear system proxy,” identify exactly which one is active. An automatic configuration script uses rules to decide where traffic goes, while a global proxy sends supported system-proxy requests to the local entry point; their failure patterns differ. During troubleshooting, temporarily switch to a mode with fewer rules to verify the baseline path, then restore the original split-routing setup.

Custom routing rules may also send traffic through the wrong outbound. Pay special attention to rule order because the core usually applies the first matching rule. A broad direct rule placed too early can hide later proxy rules. Conversely, sending local-network addresses to a remote outbound can prevent access to printers, router admin pages, or internal services. Temporarily disable newly added rules and compare with the client defaults rather than deleting the original configuration. Restore rules one at a time after the test succeeds to identify the one that changes the result.

Use a local proxy request to confirm traffic reaches the core

On desktop, bypass the system proxy and send a request directly through the client’s local port. This separates “the system proxy is not taking effect” from “the node itself is unavailable.” The example below assumes an HTTP proxy on port 10809; use the client’s current port when running it:

curl.exe -I --proxy http://127.0.0.1:10809 https://example.com/
curl.exe -v --proxy http://127.0.0.1:10809 https://example.com/

If an explicitly specified proxy returns an HTTP response but the browser still fails, focus on the browser’s proxy policy, extension conflicts, or system proxy settings. If the command immediately reports that it cannot connect to 127.0.0.1, the local port is not listening or the port is wrong. If the local port accepts the connection but the request later times out, traffic has entered the core; next check node handshakes, DNS, and routing logs. Ideally inspect inbound traffic, routing matches, and outbound errors together instead of looking only at the final error line.

After troubleshooting, leave the system proxy in a clear, intentional state. If you are done using the client, use its “clear system proxy” action before exiting. If you still need the connection, confirm that the system proxy port matches the running core. An abnormal exit can leave an old proxy address behind, preventing every app that reads the system proxy from connecting after the next boot. Reopening the client and clearing the system proxy is usually more direct than repeatedly editing values in several system panels.

02 / REMOTE HANDSHAKE

Node timeouts and handshake failures: locate the interruption layer

Distinguish TCP timeouts, TLS errors, and protocol rejection

“Node timeout” is not a single cause. The connection may fail before TCP is established, reach the server but fail during the TLS handshake, or pass TLS and then be rejected by the VMess, VLESS, or Trojan protocol layer. Use the logs to distinguish these cases. For i/o timeout, context deadline exceeded, or a timeout while connecting to the destination address, check network reachability first. For certificate-domain, handshake, or serverName errors, check the system clock and TLS parameters. For authentication failures, invalid users, or abnormal protocol responses, verify the port, user ID, and transport settings.

Do not judge node health only by the colors in the client’s latency list. A test may check only TCP setup or may perform a complete request, and results from different clients and test methods are not directly comparable. A more reliable approach is to select one node, keep the network and routing mode fixed, make a real request, and observe the full log from destination resolution through connection and handshake completion. Keep all other conditions unchanged when repeating the test so you can tell whether the error is consistent.

Check whether the destination host and port are reachable first

On Windows, use PowerShell’s Test-NetConnection to check the node domain and port. The command verifies basic network connectivity only; it does not prove that the higher-level protocol is configured correctly, but it quickly rules out a completely unreachable port:

Resolve-DnsName node.example.com
Test-NetConnection node.example.com -Port 443
Test-NetConnection node.example.com -InformationLevel Detailed

If the domain cannot be resolved, move to the DNS section. If it resolves but the TCP test fails, try another network, such as switching from home Wi-Fi to a mobile network. Failure on only one network usually points to differences in the path, router policy, or network egress. Failure everywhere requires checking the node address, port, and server status. Do not treat the result for a website’s ordinary HTTPS port as the result for the node port: both tests must use the same host and the same port.

If the node uses a domain, avoid replacing it with the resolved IP as a permanent workaround. TLS usually relies on the domain for certificate validation and SNI matching, so changing it to an IP can turn a TCP reachability issue into a certificate error. Using the IP temporarily is useful only for checking whether DNS is involved; restore the original domain and its serverName after testing.

Check the system clock, SNI, and certificate domain

TLS validation depends on the device clock. An incorrect date, time zone, or automatic time-sync setting can make a certificate appear not yet valid or already expired. Enable automatic time and time zone in system settings, then sync manually once. Virtual machines, dual-boot systems, and devices recovering from long sleep periods deserve extra attention. Fully restart the client core after correcting the clock because some connections and session state may still carry the old time conditions.

serverName or SNI must correspond to a domain covered by the server certificate; it does not necessarily have to match the connection-address field exactly. If you edited a node after importing it from a subscription, compare the original parameters and verify that the address, port, transport, TLS toggle, SNI, path, and host header still form a consistent set. Copying only the address and port while omitting transport parameters is a common cause of handshake failures. For related checks, see TLS Handshake and Certificate Error Fixes.

Compare protocol and transport parameters item by item

Protocol-layer parameters must match as a complete set. VMess requires the correct user ID, encryption, and transport combination; VLESS requires checking the user ID, flow control, and security settings; Trojan requires matching the authentication details to the TLS entry point; Shadowsocks requires the encryption method and authentication details to correspond. WebSocket, gRPC, and TCP transports also have their own path, service name, Host, and security-layer fields. Any field damaged by an extra space, line break, or manual substitution can appear as an immediate disconnect after connection.

The most useful comparison is to import the subscription again into a separate group without overwriting the existing manual configuration, then test the newly imported node. If the new node works, the old one likely drifted during editing or migration. If both nodes fail the same way, check the subscription source, network environment, or remote status. Do not enable certificate verification bypass as a permanent fix without understanding it: it may temporarily hide time, domain, or certificate-deployment problems, but it cannot correct mismatched protocol parameters.

Log stage Common symptom Check first
Before resolution Host not found, resolution failed DNS, domain spelling, network access
TCP connection Timeout, connection refused Node address, port, basic reachability
TLS handshake Certificate domain or time error System clock, SNI, TLS toggle
Protocol authentication Connection closes immediately User parameters, flow control, transport combination

If the same node succeeds sometimes and times out at other times, also check local packet loss, Wi-Fi roaming, and recovery from sleep. Run a small number of tests and record when they occur; do not create extra load with high-frequency concurrent tests. Stable errors call for configuration checks, while errors that change with the network call for path checks. This distinction can greatly shorten diagnosis.

03 / SUBSCRIPTION INPUT

Subscription update failures: from URL and response to node parsing

Confirm the subscription URL is complete and contains no extra characters

First distinguish between “no response was received” and “a response was received but parsing failed.” When copying a URL from a chat app, document, or QR code, the end may include a period, space, line break, or full-width character. Some URLs also contain long query parameters, and an incomplete copy may return a login page, error page, or empty content. Paste the complete URL again in the client’s subscription settings, check that the scheme, domain, path, and query parameters are continuous, and make sure a node-sharing link was not placed in the subscription URL field.

v2rayN usually manages multiple sources as subscription groups, while v2rayNG and v2flyNG maintain URLs in their subscription settings. After editing a subscription, save the settings and manually run an update; changing only the name does not trigger a fetch. To avoid interference from old cache data, create a temporary group, update it with the same URL, and observe the result. If the new group succeeds while the old one fails, focus on the old group’s update options, filters, and cache state.

Read the HTTP status and response type

When the log shows an HTTP status code, interpret it according to the response. Authentication failures or access denials usually relate to authorization parameters in the URL, account status, or source restrictions. A missing resource usually means the path is incomplete or the URL has changed. A server error calls for a later retry and confirmation that only this subscription source is affected. A success status does not guarantee parseable content: the response may be a webpage, login prompt, or gateway notice rather than subscription data.

On desktop, you can inspect the request without exposing the URL contents. Subscription URLs often contain sensitive authorization parameters, so never paste the complete URL into public logs or screenshots. The URL in the commands below is illustrative; run the actual test only in a local terminal with your own subscription URL:

curl.exe -I "https://subscription.example/subscription"
curl.exe -L --connect-timeout 15 "https://subscription.example/subscription" -o subscription.txt

-I reads response headers only and is useful for checking redirects and status codes. Some subscription services do not support header-only requests; in that case, use the second command to save the response, then check whether the file is empty and whether its content type is reasonable. Do not publish the response file directly because it may contain node addresses and authorization parameters. If the request redirects multiple times, verify that the client supports the flow and that the final URL still belongs to the expected subscription endpoint.

Determine whether the update request must use the current proxy

Subscription updates and node connections are related but separate paths. Some clients can update subscriptions through the proxy, but that requires an already working node. If the only node has failed and update requests are forced through it, you create a loop that cannot recover. During troubleshooting, first disable proxy-based updates and fetch the subscription over the direct network. If the direct network cannot reach it but an existing node works, test the proxied update in the other direction.

Residual system proxy settings can also affect subscription requests. If the client has exited while the system still points to its old local port, network requests made before the next client startup may all fail. Confirm that the local port is listening or clear the system proxy before updating. Corporate networks and public networks that require a sign-in page may return an authentication page on first access. Complete normal network access in a browser first, then request the subscription.

Handle format, encoding, and node-filtering issues

A subscription response may contain an encoded collection of nodes or line-by-line sharing links. The client must recognize the response format to build the node list. If parsing succeeds but the node count is zero, do not immediately assume the subscription is empty. Check keyword filters, deduplication, protocol restrictions, and rules that remove invalid nodes. An overly strict filter expression can exclude every entry, especially after group names or node remarks change.

If the log identifies a malformed line, first check whether the update still imported other valid nodes. Some clients skip individual bad records; others stop the entire process. Fetching the response again can rule out a transfer interruption. If the same position fails repeatedly, the subscription source must correct that entry. Do not manually decode and maintain a permanent copy of the subscription: node parameter updates will not reach the copy, and its address, certificate domain, and transport settings will gradually diverge.

Build a repeatable subscription-check workflow

The complete workflow is: check the system clock and basic network, verify the subscription URL, determine whether the update uses a proxy, inspect the HTTP response, review parsing logs and filters, then test a newly imported node with a real connection. Seeing a node name after an update is not enough to prove it works; verify that its parameters are complete and perform an actual access test. For detailed entry steps, see How to Import Subscriptions in v2rayN and v2rayNG.

When scheduled updates fail frequently, also check sleep, background restrictions, and network changes. Desktop devices do not run scheduled updates while asleep, and the client may need to rebuild its network after waking. On Android, restricted background activity can delay scheduled tasks. Treat automatic updates as maintenance, not the only prerequisite for a connection: keep the most recent working configuration and watch the logs and node changes after each update.

04 / THROUGHPUT

Slow connections: separate the node, path, and local overhead

First determine whether the delay is during connection setup or sustained transfer

If a webpage takes a long time to start but downloads normally once they begin, suspect DNS, the initial handshake, or connection reuse. If the page appears quickly but a large file remains slow, look at path bandwidth, packet loss, server load, or device performance. If only video, messaging, or one app is slow, check whether it uses TCP or UDP and whether routing rules send its domains through different outbounds. Calling every case a “slow node” hides important differences.

Fix the test conditions first: use the same node, network, target resource, and roughly the same time, and stop bandwidth-heavy sync or download jobs. Do not run several speed-test tools at once; concurrent requests compete for bandwidth and change node load. Test the direct network first, then enable the client. The two results show whether the bottleneck already exists in local access. If the direct network is unstable, improve the Wi-Fi signal, Ethernet connection, or router state first.

Use repeatable requests to measure time by stage

curl can report DNS, connection, TLS, and total time separately, helping identify where the delay occurs. The example accesses a reserved example domain through a local HTTP proxy; replace the port with the client’s actual value:

curl.exe -o NUL -s -w "dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} start=%{time_starttransfer} total=%{time_total}\n" --proxy http://127.0.0.1:10809 https://example.com/

High DNS time points to the DNS section. High connection time calls for checking remote reachability and path distance. Abnormal TLS time may involve packet loss, certificate-chain processing, or retransmissions. A slow time to first byte with a normal connection phase may indicate destination-site response time or remote egress load. One result does not represent long-term performance; run a few tests at intervals and look for a stable pattern. The goal is to find the slow stage, not create a ranking.

When comparing nodes, change only the node

Nodes in the same subscription may use different regions, protocols, transports, and egress paths. Keep the client mode, DNS, and destination unchanged, switch nodes one at a time, and make the same request. If every node is slow, check the local network, client mode, DNS, and device resources first. If only one node is slow, focus on that node’s path or remote load. If the same node varies greatly between networks, consider the routing quality between each access network and the node.

A client latency test reflects only the stages covered by its method. Low latency does not guarantee fast high-volume transfer, and high latency does not always mean poor sustained throughput. TCP reduces its sending window when packets are lost, which can appear as periodic speed drops. Wireless interference, mobile-network handoffs, and cross-region paths can all trigger this behavior. In real use, consider connection stability, time to first byte, and sustained transfer together instead of choosing a node by one latency value.

Check whether routing rules send one service through different paths

Modern pages request the main domain, static-resource domains, API domains, and content-delivery addresses at the same time. If rules match only the main domain, supporting resources may go direct or use another outbound, leaving the page body fast while images or scripts wait. Open the core access log and inspect the outbound rule matched by each domain during one page load. If traffic is split, adjust rules by service-domain group instead of repeatedly appending individual domains to the end of the list.

Rule order also affects performance. Too many regular expressions, broad domain matches, and duplicate rules increase evaluation complexity and make maintenance harder. Prefer clear domain, suffix, IP-range, and built-in dataset rules; put highly specific rules first and the default rule last. After changes, clear the DNS cache and restart the core so old resolutions and connections do not continue using the previous path.

Evaluate transport, multiplexing, and device resources

Connection reuse can reduce the cost of repeated handshakes, but it is not suitable for every network and server combination. If a few connections work but concurrency causes obvious stalls, compare the results with multiplexing enabled and disabled. Do not increase concurrency blindly: on limited hardware, more concurrent work increases encryption, context switching, and memory pressure. Android devices may also reduce background processing in power-saving mode or at high temperatures. On desktop, watch whether other tasks are consuming CPU, memory, or disk for long periods.

Different transports add different encapsulation overhead, but correct configuration and a stable path usually matter more than theoretical overhead. Do not change transport fields individually in pursuit of speed because client and server parameters must match. To compare protocol combinations, use complete nodes already supplied by the subscription and confirmed to work, rather than copying an address and assembling another transport configuration by hand. For protocol characteristics and selection trade-offs, see VMess, VLESS, Trojan, and Shadowsocks Compared.

05 / NAME RESOLUTION

DNS resolution problems: find out where the domain is resolved

Recognize common DNS symptoms

DNS problems often appear as failed domain lookups, a response when accessing the IP directly, a long delay before a site opens, different results for the same domain in different apps, or sites becoming unavailable after switching client modes. Failure to resolve the node domain prevents the core from reaching the remote server; failure to resolve a destination domain may affect only particular sites. First determine whether the failed name is the “node address” or the “destination,” because they may use different resolution paths.

A browser may use its own secure DNS, the operating system may use another server set, and the core may resolve domains from proxied requests according to its configuration. A single device can therefore have several DNS paths at once. Browser success does not prove that system resolution works, and a successful system command does not prove that the core got the same result. Use browser settings, system network configuration, and core logs together to identify the actual resolver.

Start by checking the system’s resolution result

On Windows, use Resolve-DnsName or nslookup; on macOS and Linux, use dig or nslookup. Test the node domain first, then the destination domain showing problems, and record the response type and addresses:

Resolve-DnsName node.example.com
nslookup node.example.com
nslookup example.com

# macOS or Linux
dig node.example.com
dig example.com A
dig example.com AAAA

A timeout means the current DNS server did not respond in time. A nonexistent-domain result calls for checking the spelling and record status. If an address is returned but the connection still fails, the problem has moved from resolution to routing, the port, or the handshake. If both IPv4 and IPv6 addresses are returned while the current network has incomplete IPv6 connectivity, an app may try an unreachable address first and wait before falling back. You can temporarily compare A and AAAA connection results, but do not hide a network configuration problem by permanently removing protocol support.

Clear caches and eliminate stale results

The system, browser, and client core may all cache DNS results. After changing DNS settings, old connections and cache entries do not disappear immediately. Close related browser tabs, stop the core, clear the system cache, and restart the client in that order. On Windows, run:

ipconfig /flushdns
Clear-DnsClientCache
Get-DnsClientServerAddress

Clearing the cache only makes the next request resolve again; it cannot fix a wrong server address, routing rule, or domain configuration. If things work briefly after every cache clear and then fail again, identify which component is writing the bad result, such as a network switch, router-provided DNS, browser-specific resolution, or a client rule sending requests to an unreachable server.

Understand local resolution, remote resolution, and domain rules

When an app sends a domain to a SOCKS or HTTP proxy, the name may be resolved locally first, or it may remain a domain inside the core, which then selects the DNS server. This affects routing matches. If the name is converted to an IP too early, domain-based rules may lose the original name; if it remains a domain, the core needs a reliable DNS outbound. Decide which layer should resolve the name instead of stacking options that override one another.

Core DNS settings typically include server lists, matching domains, and query strategies. Rules must align with outbound paths: the server used to resolve a node domain must be reachable before the node exists, while DNS that depends on the proxy outbound cannot also perform the first lookup needed to establish that proxy. The safest baseline is to retain one path that can resolve the node address over the direct network, then route other queries according to their domains and requirements.

Check hosts files, filters, and browser-specific settings

Static records in the system hosts file usually take priority over ordinary DNS queries. Old test records, wrong addresses, or duplicate entries can keep a domain pointed at an obsolete destination. Only edit records you knowingly added, and keep a backup first. Security software, router filters, parental controls, and corporate network policies may also return specific addresses or block queries; compare results on another network.

A browser’s independent DNS setting may bypass the system path. If only one browser is affected, test with a clean profile or another browser, then check for independent resolution, proxy extensions, or cache policies. If every app is affected, start with the system and core. Avoid letting browser extensions, system proxy tools, and the V2Ray client modify the same layer at once, or it will be difficult to tell which path a successful request used.

Symptom Likely location How to verify
Node domain cannot be resolved System DNS, basic network Stop the client and query the node domain
Only the browser works Browser-specific DNS or system proxy differences Compare command-line results with browser settings
Domain fails, IP connects Destination-domain resolution path Query A and AAAA records and inspect the core log
Recovers after switching networks DNS or routing supplied by the current network Record the servers and resolution results on both networks

After fixing the issue, verify node-domain resolution, destination-domain resolution, and real access separately. A returned DNS address proves only that resolution finished; routing, connection, and protocol handshaking still follow. Recording the three results separately makes it easier to see which layer changes again after a network switch or rule adjustment.

06 / APPLICATION ROUTING

System proxy not working: check browsers and terminals separately

Understand the limits of the system proxy first

The system proxy is a set of connection settings that apps may read; it does not automatically capture all network traffic. Browsers and some desktop software usually read it, while command-line tools, games, background services, and apps with their own network stack may ignore it. This can make the browser use the client while the terminal connects directly, without indicating a core failure. First determine which proxy methods the target app supports, then choose the system proxy, environment variables, in-app proxy settings, or TUN mode.

For a detailed scenario comparison, see Troubleshooting the System Proxy in Browsers and Terminals. The key method is consistent: verify the local port, confirm the system proxy values, then check whether the app reads them. Do not infer that traffic has entered the core from a tray icon or client-menu status alone.

Verify the proxy address, type, and port

HTTP, SOCKS, and mixed proxies are not interchangeable. The proxy type entered in an app must match the client’s listening entry point. Putting a SOCKS port in a system-proxy field that supports only HTTP may fail immediately; using an HTTP port as SOCKS produces a handshake error. Copy the address and port from the client settings and confirm that the core is still listening after restart.

On Windows, view the current user’s proxy configuration and compare it with a request that specifies a proxy directly:

netsh winhttp show proxy
Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
curl.exe -I --proxy http://127.0.0.1:10809 https://example.com/

WinHTTP and ordinary desktop apps may obtain proxy settings from different sources, so the result of netsh winhttp show proxy does not mean that the browser uses the same configuration. Judge each program separately. If an explicitly specified proxy works but the app still connects directly, the node and local port are basically usable; focus on the app settings. If the explicit proxy also fails, return to the local-listener or node sections.

Handle variable-name casing in terminal tools

Many command-line programs read HTTP_PROXY, HTTPS_PROXY, and ALL_PROXY, but tools differ in their handling of variable case and supported schemes. Temporary variables are suitable for a single test and disappear when the terminal closes. PowerShell example:

$env:HTTP_PROXY="http://127.0.0.1:10809"
$env:HTTPS_PROXY="http://127.0.0.1:10809"
curl.exe -I https://example.com/

Remove-Item Env:HTTP_PROXY
Remove-Item Env:HTTPS_PROXY

macOS or Linux shells can use:

export HTTP_PROXY="http://127.0.0.1:10809"
export HTTPS_PROXY="http://127.0.0.1:10809"
export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
curl -I https://example.com/

unset HTTP_PROXY HTTPS_PROXY http_proxy https_proxy

For a SOCKS entry point, confirm that the tool supports the required syntax and whether domains are resolved locally or by the proxy. Do not leave proxy variables permanently in startup files when the client may not be running; otherwise terminal traffic will point to an empty port. If permanent settings are necessary, document how to remove them and ensure the port remains stable when configurations change.

Check automatic configuration scripts and bypass lists

An automatic proxy configuration decides whether to connect directly or use a proxy based on the URL or hostname. If the script cannot load, its cache is stale, or a rule omits a destination, some sites may bypass the client. Temporarily switch to an explicit manual proxy to confirm that the local port and node work, then restore the automatic script. Restart the browser afterward so it rereads the system settings and script.

Bypass lists commonly include local addresses, LAN hosts, or selected domains. A range that is too broad can send many destinations direct; an incorrect wildcard may match every subdomain. Conversely, failing to bypass local addresses can block internal devices. Keep loopback addresses and clearly defined private ranges first, then restore custom entries one by one. System settings, client rules, and browser extensions may each have their own bypass list, so avoid maintaining duplicates in all three places.

TUN mode requires a different checklist

TUN mode handles more traffic that ignores the system proxy through a virtual network interface, but it introduces routing tables, DNS capture, system permissions, and conflicts with other network software. If enabling it cuts off all access, check whether the virtual interface was created, whether a default route was added, whether DNS points to a valid entry point, and whether the client has the required permissions. After exiting the client, confirm that the routes and DNS settings have been restored.

Do not make TUN mode the first response to a system-proxy failure. Prove that the node and ordinary local proxy port work first, then enable TUN so any new issue is confined to the virtual-interface layer. If the device also runs virtual-machine networking, container networking, corporate access software, or another route manager, disable them one at a time for comparison. Conflicts usually come from route priority or DNS takeover order, not the node protocol itself.

Final verification should cover three request types: a browser reading the system proxy, a command-line request with an explicitly specified proxy, and an app that does not support the system proxy accessing through its own settings or TUN. Success on all three makes the configuration boundaries clear. If one category fails, fix that entry point without resetting the other working parts.

07 / CLIENT RUNTIME

Client crashes or core exits: preserve evidence and recover layer by layer

Distinguish a UI exit, core exit, and configuration-load failure

A disappearing client window, a visible interface with stopped connections, and a Start action that immediately returns to an inactive state indicate different layers. When the UI process crashes, the tray icon may disappear too. When the core exits, the interface usually remains and shows an error log. A configuration-load failure often occurs after switching nodes or changing settings, before the core starts listening. First identify which layer exited, then choose application logs, core logs, or system events.

Do not reinstall immediately after an incident. Save the time, steps, and final log lines, and note whether you had just imported a subscription, edited routing, changed core settings, resumed from sleep, or updated the system. A reproducible sequence is far easier to diagnose than “it crashes sometimes.” Before asking publicly for help, remove node addresses, subscription parameters, user IDs, and other credentials; keep only the error type and processing stage.

Roll back from the most recent configuration change

If the issue began after importing a new node, switch back to a verified node. If it began after editing routing, temporarily disable the new rules. If it began after changing the port, check whether the new port is occupied. If it began after enabling TUN, return to ordinary system-proxy mode. Roll back one category at a time and restart the client after each change. Deleting all configuration may restore service temporarily, but it destroys diagnostic evidence and can let the same error return after reimport.

When the configuration is JSON, common errors include trailing commas, missing quotation marks, incorrect nesting, and numbers written as unrecognized text. The following is a structurally complete minimal routing fragment showing arrays, objects, and comma placement; merge it with the complete structure generated by the client before use:

{
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "geosite:private"
        ],
        "outboundTag": "direct"
      }
    ]
  }
}

If you are unfamiliar with the full configuration structure, edit through the client interface instead of replacing the entire file with a fragment. Client-generated fields also reference inbound and outbound tags, and mismatched tag names can prevent startup. If the log identifies a field or line number, inspect the parent object around it rather than changing only the character named in the error.

Check ports, permissions, and the working directory

A port conflict is a common reason for the core to exit immediately. Use a port-checking command to find the process ID, then determine whether it belongs to an old core, another proxy tool, or a legitimate system service. Do not terminate an unknown system process. Close the related application or choose an unused port for the client instead. If an old core remains, stop it from the client, wait for the process to exit, and then start again.

TUN, route installation, and some system-level features require appropriate permissions. If ordinary proxy mode works but TUN fails to start, check permission prompts, virtual-interface creation, and system security policies. Without write access to its installation directory, the client may also fail to save configuration or logs or unpack runtime components. Place the program in a normal directory writable by the current user, avoid running it from inside an archive, and do not launch the same configuration from multiple directories.

Isolate subscription data, the client UI, and the core

v2rayN is a desktop client for Windows, macOS, and Linux; v2rayNG uses the Xray core, and v2flyNG uses the v2fly core. Their interfaces, configuration management, and core implementations are different layers. If a node imports successfully but the core cannot load it, the parameters may not match the current core’s capabilities. If the core runs independently but the UI crashes, focus on client state files, the UI runtime environment, and system logs.

For an isolated test, create a new blank configuration directory or use the client’s backup and restore feature; do not overwrite the only copy of your data. Start with a basic environment containing no subscription or custom routing, then import one known configuration at a time. If the blank environment is stable but importing causes crashes, focus on configuration or data. If it also crashes when blank, investigate installation files, the runtime environment, permissions, and system compatibility. If you need to obtain the client again, choose the installer matching your platform and architecture from the Download page.

Handle growing logs, sleep recovery, and security-software blocks

Keeping verbose logs enabled for a long time increases disk writes and file size. When disk space is low, saving configuration, updating subscriptions, and writing logs may all fail. After troubleshooting, restore the normal log level and remove old logs using the client’s supported method. Do not manually lock or move a log file while the core is writing to it, as this can create a new failure.

After a device wakes from sleep, the adapter address, DNS, and default route may have changed while the core still holds connections from before sleep. Stop the connection, wait for the system network to stabilize, and restart the core; this is often faster than rebooting the device. If the issue returns after every sleep cycle, record adapter, route, and log changes during recovery to distinguish network rebuilding from a client-process failure.

Security software may prevent a newly downloaded executable from listening on a port, creating a virtual interface, or accessing the network. Check system security records for an explicit block of the client or core process and handle that specific path. Do not disable all system protection as a permanent solution; identify the exact blocked object from the event record and restore operation without changing unrelated rules.

After recovery, run a complete regression check: start the client, verify the listening port, connect to a node, toggle the system proxy, update the subscription, and clean up on exit. A window opening successfully is not enough to prove the issue is gone. If it remains reproducible, record the minimum reproduction steps and the relevant logs, then check the corresponding entry in the Frequently Asked Questions.

08 / ANDROID RUNTIME

Android Tips: permissions, background disconnects, and per-app proxying

Confirm system permission before the first connection

On Android, v2rayNG and v2flyNG usually create a local virtual network through the system VpnService. The first connection displays a system permission prompt; the client can capture the relevant traffic only after you approve it. If no connection-status icon appears, the log immediately returns an authorization error, or the UI remains disconnected after tapping Connect, check whether permission was denied and whether another network app is already using the same type of interface.

The system generally allows only one active connection of this type at a time. Before switching clients, stop the existing connection, wait for its status icon to disappear, and then start v2rayNG or v2flyNG. Force-stopping the previous app without disconnecting cleanly may leave the old interface active briefly. Disconnect it in system network settings or restart networking before trying again. Do not let multiple apps repeatedly auto-reconnect, or one app may replace a connection just established by another.

For background disconnects, check battery and process restrictions first

Disconnecting a few minutes after locking the screen, stopping after switching apps, or failing to recover automatically after the system clears background processes usually points to battery optimization, background-activity limits, or device-vendor process management. Add the client to the system’s allowed-background list, permit necessary background network activity, and avoid manually ending it from the task-cleanup screen. Settings names differ across Android versions, but the requirement is the same: the client process and VpnService must keep running after the screen locks.

Disabling one battery-optimization setting may not be enough. Some devices separately provide app power policies, auto-start management, background data, sleeping apps, and lock-screen cleanup. Check each item, then lock the screen and make a real request after waiting, rather than relying on the status-bar icon. If the icon remains but requests fail, also check whether the network switched from Wi-Fi to mobile data and whether the core rebuilt its connection successfully.

Android power-saving mode may delay background tasks and network access, affecting subscription updates, keepalives, and network recovery. Temporarily disable it for comparison; if the issue disappears, adjust the policy for this app instead of changing the entire device’s power settings permanently. For fuller instructions, see v2rayNG Permissions, Power Saving, and Per-App Proxying.

Handle Wi-Fi and mobile-network changes

Switching from Wi-Fi to mobile data changes the local IP, default route, and DNS, so existing TCP connections usually cannot be reused. The client should detect the change and reconnect, but system restrictions, weak signal, or core state can delay recovery. If access fails after a switch, wait until the underlying network itself works, then stop and reconnect in the client. Do not tap the toggle repeatedly in quick succession.

If Wi-Fi works but mobile data fails, use the same node to compare destination-port reachability and IPv4/IPv6 behavior. For the reverse case, check router DNS, LAN filtering, and Wi-Fi sign-in status. Public Wi-Fi often requires a login page; complete authentication in a browser with the client off, then reconnect. When only one network fails, do not reset the subscription or node parameters because the same configuration already works on the other network.

Make “include” and “exclude” explicit in per-app proxying

Per-app proxy settings usually offer either proxy only selected apps or bypass selected apps. The names are similar, but the results are opposite. Confirm the active mode before enabling it, then check whether the target app is listed. In “proxy only” mode, unselected browsers and test tools bypass the client; in “bypass” mode, listed apps use the direct network. During troubleshooting, temporarily disable per-app rules, confirm the global connection works, and then add or exclude apps one at a time.

An app update or reinstall may change its system identifier, so an old rule may no longer match. If an app that worked before suddenly connects directly or loses access after an update, reopen the per-app list and save it again. System components, embedded web pages, and external browsers launched by an app may run as different processes; selecting only the main app may not cover the full sign-in flow. The core access log can confirm whether requests actually entered the client.

How Android DNS interacts with Private DNS

System Private DNS, the client core’s DNS, and an app’s own resolver may all be active at once. If domains fail after connection while direct IP requests work, first check whether Private DNS is set to Automatic, Off, or a specific hostname, then inspect DNS errors in the client log. If the specified Private DNS host is unreachable on the current network, resolution may fail both before and after the virtual network is created. Temporarily switch to the system’s automatic mode for comparison, then decide on a long-term setting.

When enabling local DNS capture, ensure queries can complete through the current outbound while the node domain still has a usable initial resolution path. As on desktop, DNS needed to resolve the node cannot depend entirely on that node before it exists. If stale results persist after a network change, stop the connection, toggle airplane mode on and off to rebuild networking, and reconnect the client. This interrupts all current network tasks, so save your work first.

Shortest workflow when an app connects but cannot access sites

First disable per-app proxying, select a verified node, and confirm that system permission is granted. Then check whether the connection log shows a completed node handshake and test domain access in a browser. If the handshake fails, follow the node-timeout section. If the handshake succeeds but there are no access logs, app traffic is not entering the virtual network; check permission and per-app settings. If access logs appear but DNS errors are reported, address Private DNS and core DNS. If the request reaches the outbound and then times out, compare Wi-Fi and mobile data.

If only one app fails, check its independent proxy, Private DNS, background-data restriction, or Wi-Fi-only download setting. Clearing all client data deletes subscriptions and routing settings, so it should not be the first step. A safer approach is to export or record the current settings, create a minimal configuration for comparison, and decide whether a reset is necessary afterward. v2rayNG is primarily used for Xray core configurations, while v2flyNG can serve as an alternative for the v2fly core. When comparing clients, use the same complete node and remember that their supported core capabilities may differ.

Android symptom Check first Action
Stops immediately after tapping Connect System permission, configuration-load log Grant permission again and verify node parameters
Disconnects after the screen locks Battery optimization, background activity Allow the client to keep running in the background
Stops working after a network switch Route rebuild, DNS, node reachability Confirm the basic network, then reconnect
Only some apps fail Per-app mode, app-specific settings Disable filtering to test, then restore settings one by one

Mobile issues are often triggered by the system lifecycle and network changes together. A stable configuration must do more than show a connected status: it should remain active after the screen locks, recover when switching between Wi-Fi and mobile data, and send the target app through the intended routing rule. Test the relevant scenario after every change instead of ending the investigation after a brief foreground success.

NEXT CHECK

Narrow the fault to one stage of the path

Record the symptom, current network, client, node, proxy mode, log stage, and actions already taken. If the basic configuration is not complete, return to Quick Start; if you need another client, choose one for your platform on the Download page.