Diagnostics · Complete Troubleshooting Guide

V2Ray Client Troubleshooting Diagnose by Symptom

From no internet, server timeouts and failed subscriptions to speed, DNS, system proxy and mobile issues, split into nine chapters, each with a diagnostic order and fixes.

v2rayN · v2rayNG · v2flyNG 9 symptom chapters Log keyword reference Runnable command examples

How this page and the Setup Guide split the work

The setup guide walks the main path once: import a subscription → choose a mode → connect → verify. This page does not repeat those steps; it is organised by symptom, giving a diagnostic order and fixes for each type of problem. If you are installing for the first time, start with the Setup Guide; if you can already connect but something is wrong, pick the matching chapter from the list below.

Symptom Quick Reference

Symptom you seeCheck first
Client shows connected, but pages won't openChapter 02: local ports, proxy tests and routing rules
Log shows timeout / refused / handshakeChapter 03: server reachability, authentication and TLS parameters
Server list is empty, subscription update returns an errorChapter 04: subscription fetch, group filters and overwrite
Connects but is slow and drops frequentlyChapter 05: transport, multiplexing and route comparison
A few domains won't open or resolve incorrectlyChapter 06: DNS configuration, domain sniffing and cache refresh
Command line works through the proxy, browser doesn'tChapter 07: system proxy registration and port conflicts
Double-click does nothing, core keeps restartingChapter 08: config validation, permissions and security software blocking
Android connection drops or gets taken overChapter 09: VPN authorization, battery policy and per-app proxy

01 / Diagnostic BaselinePin the variables first, then rule out layer by layer

The most common mistake in troubleshooting is changing several configuration items at once. Swap the server, protocol, routing and DNS together, and even if the connection recovers you cannot tell which change did the work. Every chapter on this page follows the same order: freeze the current environment, split the chain into segments, and verify starting from the segment closest to the client. Only move on to the next segment once the current one passes.

A complete proxy chain splits into six segments: the application issuing the request, the local inbound port, the local core process, the outbound connection (protocol and transport), the remote server, and the target site. Each segment has checkpoints you can verify independently; the table below lists them together, and the troubleshooting steps in later chapters all revolve around these segments.

Chain segmentHow to verifyPass criteria
Local inboundnetstat or lsof to check the portA process is listening on the recorded port at 127.0.0.1
Local coreCheck the first log line and the process statusCore starts without errors and the log keeps outputting
Outbound to servercurl from the command line through the local proxyResponse headers from the target site are returned
Remote serverSwitch to a known working server for comparisonThe new server can reach the same site normally
System proxyCheck the proxy entry in system settingsAddress and port match the client settings

Before you start, pin down four pieces of information

  1. Client and core version — the first line of the v2rayN log prints the core name and version. Different cores (V2Fly and Xray) support different ranges of the same configuration, so confirm the core first when you hit a field error.
  2. Local inbound ports — note the SOCKS and HTTP ports in the settings; every command-line check below uses these two ports.
  3. Current outbound parameters — protocol (VLESS, VMess, Trojan and so on), transport (tcp, ws, grpc), whether TLS is enabled, and the SNI or Host values.
  4. System proxy and TUN status — whether the client has written the proxy into the operating system, or is capturing all traffic in TUN mode. The two modes call for completely different approaches.

Also keep a troubleshooting log recording the time of each reproduction, the network environment at the time (Wi-Fi or wired, whether you switched networks), and the configuration items you changed. Most "works sometimes, fails sometimes" problems reveal a pattern in this log — for example, only on one particular network, or only after waking from sleep.

Raise the log level and reproduce once

The default log level usually outputs warnings only, which is not enough detail. Before reproducing a fault, set the level to info or debug, then set it back immediately afterwards so the log file does not keep growing. Every log line carries a timestamp, so you can line it up with system events to the second. The structure of the log and how to read common errors is broken down in How to Read v2rayN Runtime Logs.

Run the core separately from the command line

The log panel in the client interface is essentially the standard output of the core process. After exporting the configuration as config.json, you can run it once by hand from the command line to rule out interference from the interface layer:

# Xray core: validate the config only, do not start the service
xray run -test -config config.json

# Xray core: start in the foreground, logs print straight to the terminal
xray run -config config.json

For the V2Fly core, just swap the commands for v2ray test -config config.json and v2ray run -config config.json; the parameters mean the same thing.

Change only one variable at a time

During troubleshooting, retest and record the result immediately after each change. Once several variables stack up, you cannot attribute the fix even if the problem disappears, and the next time the same symptom appears you start over from scratch.

One last rule of thumb: if several servers in the same subscription time out at once, suspect the local network, the subscription itself or the client configuration first; if only one or two servers time out, suspect the server and the route it sits on. This rule decides whether you head to Chapter 03 or Chapter 04 next.

02 / Symptom OneShows connected, but pages won't open

"Connected" in the client only means the local core process started successfully and the inbound port is listening; it does not mean data can pass through the outbound to the target site. This symptom covers the widest range, and the four steps below narrow it down to a specific segment.

Step 1: confirm the local port is listening

# macOS / Linux
lsof -nP -iTCP:10808 -sTCP:LISTEN

# Windows
netstat -ano | findstr "10808"

No output at all means the inbound did not start. Check whether the client process is actually running and whether the inbound port in the configuration is taken by another program; see Chapter 07 for how to handle it.

Step 2: test the proxy directly with curl, bypassing the browser

curl -x socks5h://127.0.0.1:10808 -I https://www.example.com
curl -x http://127.0.0.1:10809 -I https://www.example.com

The two commands test the SOCKS and HTTP inbounds separately. How to read the results:

  • Both return response headers: the proxy chain is fine, so the problem is in the browser or the system proxy layer — go to Chapter 07.
  • Neither works: the outbound or the remote end is at fault — go to Chapter 03.
  • Only one works: the inbound configuration or protocol type for that port is wrong; check whether both inbounds are enabled in the settings.

The h in socks5h means the domain is resolved by the proxy; without it, the local machine resolves the domain to an IP first and then hands it to the proxy. Testing with socks5h rules out interference from local DNS; the difference between the two is covered in Chapter 06.

Step 3: check whether a routing rule is sending the target out as a direct connection

The common split-routing presets in clients usually include a rule that routes by domain region. If the target domain is judged to be direct and the direct route itself is broken, the browser behaves exactly as if the proxy were not working. To pin it down, set the log level to info, visit the target site, and check whether the outbound tag for that request in the log is direct or proxy.

If it is a misclassification, there are two ways to handle it: add the domain to the proxy rules in the routing settings, or temporarily set the default outbound to the proxy to confirm whether the rule is the cause. A routing rule skeleton you can adapt:

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      { "type": "field", "domain": ["geosite:cn"], "outboundTag": "direct" },
      { "type": "field", "domain": ["geosite:geolocation-!cn"], "outboundTag": "proxy" }
    ]
  }
}

Rules are matched from top to bottom and the first hit wins, so more specific entries must come first. This topic is covered in more depth in Routing Rules in Practice.

Step 4: compare against a direct connection to rule out a problem with the target site itself

Visit the same site over a network that does not go through the proxy. If the direct connection fails too, the problem is not in the client and there is no point changing more settings. This step looks trivial, but it heads off a fair number of cases where you troubleshoot for ages only to find the site itself is down.

curl test resultConclusionNext step
Both work, browser doesn'tSystem proxy or browser layerChapter 07: check system proxy registration and ports
Neither worksOutbound or remote endChapter 03: reachability and handshake parameters
Proxy works but the target site does not respondRouting misclassification or site outageCheck the routing log and compare with a direct connection

Port types are not interchangeable

The SOCKS port and the HTTP port cannot be swapped. Put the HTTP port into an application that only accepts SOCKS, or the other way round, and the symptom is always "the connection is established but pages won't open".

03 / Symptom TwoServer timeouts and handshake failures

What these problems have in common is that the local core is already working but data cannot get out. The log shows clear error lines, so classify by keyword first and then decide which direction to investigate — far faster than changing settings one by one.

Log keyword reference

Log keywordUsual meaningCheck first
i/o timeout、context deadline exceededThe connection to the server was not established within the timeoutServer address and port reachability, local network egress
connection refusedNothing is listening on the target portWhether the server side is running, whether the port number is wrong
EOF、connection reset by peerThe connection was dropped after being establishedMismatched transport parameters, interference from middleboxes
tls: handshake failure, certificate-related messagesThe TLS handshake did not completeSNI, certificate, REALITY public key
invalid user、rejectedAuthentication failedUUID or password, system clock skew

Test reachability first, then suspect the configuration

# Linux / macOS: test whether a TCP port can be connected to
nc -vz 203.0.113.10 443

# Windows PowerShell
Test-NetConnection -ComputerName 203.0.113.10 -Port 443

The address in the example comes from a documentation-only range; replace it with your own server address and port when you use it. How to read the result:

  • Port unreachable: the server is not listening, the server-side firewall is blocking, or the route is unreachable. Confirm the server state first, then consider changing the port or the route.
  • Port reachable but the client still reports a timeout: check whether the address in the client is a domain or an IP. If it is a domain, resolution may be the problem — go to Chapter 06.
  • ICMP ping failing does not mean the port is unreachable. Most servers do not answer ping by default, so go by the TCP test result.

Authentication parameters and clock skew

The VMess protocol uses a timestamp in authentication, and the server rejects the connection outright when the clock difference between client and server exceeds the allowed range. Check whether automatic time synchronisation is enabled; virtual machines and dual-boot devices commonly drift after long sleep periods. Credential fields such as UUID and password are case-sensitive, and it is easy to drop trailing characters when copying.

TLS and transport parameters

  • For servers with TLS enabled, the SNI must match the server certificate; a wrong value produces a handshake failure.
  • REALITY servers need the correct serverName and public key (publicKey); both are required. How these two parameters work is explained in REALITY and XTLS Vision Explained.
  • With ws or grpc transport, path and host must match the server side and are case-sensitive.
  • The host field of the transport layer and the SNI of TLS are two different parameters — do not mix them up.

Re-import the share link once

The easiest way to rule things out is to import the server share link again. Manual transcription easily drops case or special characters, and a fresh import eliminates that class of error in one go.

If several servers time out at once and the reachability tests all fail, shift your suspicion from the individual server to the local network egress or the subscription itself; if only one server times out at fixed times of day, note the pattern and check with the service provider.

04 / Symptom ThreeSubscription update failures and abnormal server lists

The subscription is the source of the server list. A failed update shows up as all servers disappearing, the list stuck on old content, or an error dialog after the update button spins. Confirm whether the subscription content itself can be fetched first, then look at the client side — do not reverse the order.

Step 1: fetch the subscription once from the command line

curl -L -A "v2rayN" -o sub.txt "https://example.com/api/v1/client/subscribe?token=xxxx"
head -c 300 sub.txt

The first command saves the subscription content to a file; the second prints the first 300 characters so you can judge the response format:

  • Returns a base64 string: this is the normal encoding for a server list, so the problem is on the client side.
  • Returns an HTML page: the subscription URL has expired, or the request was intercepted by a middlebox and redirected to an error page.
  • Returns 404 or 403: the address has expired, the token is wrong, or the server restricts the User-Agent. The -A "v2rayN" in the example sets the User-Agent; some servers use it to tell where requests come from.

You need a server before you can update a subscription

If the subscription server is only reachable through a proxy and the client currently has no working server, you fall into a loop: no server → cannot update the subscription → still no server. There are two ways out: enable "update subscription through proxy" in the subscription settings and import one working server by hand first; or complete one update on a network that can reach the subscription server directly, then switch networks once the servers are imported.

Servers disappear or shrink after an update

  • Group filters: check whether a group filtered by name or region is set; filtered-out servers are not displayed.
  • Overwrite: some clients replace the whole group on subscription update, so manually added servers should live in a separate group to avoid being overwritten.
  • Deduplication: multiple routes to the same server are merged into one after import, so a lower count is normal.
  • Server-side changes: the subscription content itself changed; go by the latest fetch.

Automatic vs manual updates

The update interval in the settings determines how often automatic updates run. Manual updates usually have two entry points: a full update re-fetches and overwrites the server list, while refreshing only the subscription content leaves the currently selected server untouched, which suits keeping things as they are while the connection is stable. During troubleshooting, turn automatic updates off first so background tasks do not interfere with your judgement.

Response contentDiagnosisAction
base64 stringSubscription is fineCheck the group and update entry on the client side
HTML pageAddress expired or request interceptedAsk the provider for the new address
404 / 403Wrong token or restricted sourceCheck the address and retry with a different User-Agent if needed
Connection timeoutThe current network cannot reach the subscription serverSwitch networks, or enable update through proxy

A subscription URL is as sensitive as a credential

Subscription URLs usually carry a token and are equivalent to account credentials. Before posting a screenshot or a forum message, make sure the address is redacted — never paste it in full.

05 / Symptom FourConnects but is slow and drops frequently

"Slow" covers at least four different behaviours: slow handshake (a long wait before the page opens), low bandwidth (download speed won't climb), jitter (fast then slow), and dropouts (the connection breaks). Each calls for a different approach, so match your case before you start changing things.

It also helps to separate three common latency figures: ping measures the ICMP round trip, real connection latency measures how long the proxy chain takes to establish, and a download speed test measures actual throughput. They measure different things and cannot substitute for one another. Comparing the Three Latency Measurements sets out when each figure applies and how it is commonly misread.

Start with a direct-connection comparison

On the same device, at the same time of day, download a large file from a same-region address without going through the proxy and record the speed. If the direct connection is unstable too, the problem is in the local network or the ISP egress, and further client tuning is pointless.

Confirm the traffic really goes through the proxy

Check the outbound tag for the target domain in the log. Slow speeds are sometimes caused by a rule sending the target out as a direct connection, and the direct route happens to be congested — which looks like "the proxy is slow".

Transport and multiplexing

  • Multiplexing (mux): merging several connections onto one TCP connection cuts handshake overhead on low-loss routes; on high-loss routes, one bad connection drags down every request multiplexed onto it. Test with it on and off.
  • Transport: tcp is the most direct; ws and grpc are more stable on certain networks but add a layer of encapsulation and its overhead.
  • Encryption algorithm: throughput differs noticeably between algorithms on weaker devices, so try switching and compare.

MTU and fragmentation

When large packets are dropped on the route, the typical symptoms are "pages open but downloads stall" or "video takes a long time to buffer". Reduce the MTU step by step at the client or system level, by 8 to 16 bytes each time, and watch for improvement. Reconnect once after the change for it to take effect.

Common causes of dropouts

  • Server load changes or a route switch;
  • Local network switching: moving between Wi-Fi and wired, or a mobile network changing cell towers;
  • The proxy process ends up in a bad state after the system sleeps and wakes, and needs one reconnect;
  • Long-idle connections are cleaned up by middleboxes and recover after reconnecting.
SymptomSuspect firstHow to verify
Long wait before pages openHandshake overhead, multiplexing settingsToggle mux and compare, watch real connection latency
Download speed won't climbRoute bandwidth, encryption algorithmSwitch servers and compare with a direct connection
Fast then slowRoute congestion, packet lossRun speed tests at several fixed times and compare
Connection breaks frequentlyNetwork switching, sleep and wakeThe time pattern in your troubleshooting log

Run speed tests at fixed times

The same route performs very differently at peak hours and in the small hours, so a single result proves nothing. Take at least three measurements at different times before drawing a conclusion.

06 / Symptom FiveSome domains resolve incorrectly

The typical pattern: most sites work, a few domains won't open; or the resolved IP does not match the real one; or sites in a particular region show noticeably higher latency. What they share is that the problem sits at the step where a domain becomes an IP.

Where a domain gets resolved

When you use a SOCKS proxy, where the domain is resolved depends on the client settings:

  • socks5h (with the h) or domain sniffing enabled: the domain goes to the core and is resolved according to the DNS configuration;
  • socks5 (without the h): the local machine resolves it to an IP first and then hands it to the proxy, so local DNS problems are carried straight into the proxy chain.

When troubleshooting, test once with socks5h first — it quickly separates "a local DNS problem" from "a proxy chain problem".

Adjust the client's DNS configuration

{
  "dns": {
    "servers": [
      { "address": "1.1.1.1", "domains": ["geosite:geolocation-!cn"] },
      { "address": "223.5.5.5", "domains": ["geosite:cn"] }
    ]
  }
}

This configuration sends domains from different regions to different DNS servers, cutting the extra latency of cross-region resolution. Restart the core process after the change for it to take effect.

Routing rules need domain information to match

Domain-based routing rules need the domain first. If traffic enters the core as an IP, domain rules cannot match and the request falls through to the default outbound. With domain sniffing enabled, the core can recover the domain from HTTP requests and TLS handshake information:

{
  "inbounds": [
    {
      "tag": "socks-in",
      "port": 10808,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "sniffing": { "enabled": true, "destOverride": ["http", "tls"] },
      "settings": { "udp": true }
    }
  ]
}

Once sniffing is on, domain rules and domain-based routing work as intended. If a rule "is clearly written but does not take effect", check whether sniffing is enabled first.

Targeted fixes for a single domain

If only a few domains resolve incorrectly, you can hard-code the correct address in the hosts configuration, or point that domain at a specific server in the DNS configuration. The smaller the change, the easier it is to verify and the less likely it is to introduce new problems.

Flush the system DNS cache

# Windows
ipconfig /flushdns

# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

# Linux(systemd-resolved)
sudo resolvectl flush-caches
SymptomPossible causeAction
A few domains won't openAbnormal resolution resultHard-code in hosts or set a dedicated DNS server
Domain rules do not take effectSniffing is not enabledEnable sniffing in the inbound configuration
No change after editing the configDNS cache not flushedRestart the core and flush the system cache
High latency to sites in one regionCross-region resolutionSplit DNS servers by region

The DNS section needs a restart to take effect

After changing the DNS configuration you must restart the core process; some clients do not hot-reload the DNS section, so clicking save in the interface shows no change.

07 / Symptom SixSystem proxy not working and port conflicts

The typical pattern: the client shows connected, the browser won't open pages, but curl from the command line through the local proxy works. That means the proxy chain itself is fine and the problem is that the system proxy was not written, was written in the wrong place, or the port does not match.

Where to check the system proxy on each platform

PlatformWhere to check
WindowsSettings → Network & Internet → Proxy; or Internet Options → Connections → LAN settings
macOSSystem Settings → Network → current service → Details → Proxies
LinuxThe desktop environment's network proxy settings, or the http_proxy / https_proxy / all_proxy environment variables in the shell

Common reasons the system proxy won't stick

  • The client lacks the permissions to change system proxy settings;
  • Another proxy application is running and holds the same setting;
  • The browser uses its own proxy configuration or a proxy extension and ignores system settings;
  • The system proxy only affects applications that read system settings; some applications need TUN mode to be captured.

TUN mode vs system proxy

ItemSystem proxyTUN mode
ScopeApplications that read system proxy settingsAll traffic, with rule-based exclusions
PermissionsNormal permissions, with a one-time authorisation on some platformsRequires administrator or root privileges
Typical problemApplications that ignore system settingsRouting table conflicts, contention with other VPNs

Port conflicts

# Windows: find the process ID holding the port
netstat -ano | findstr ":10808"
tasklist | findstr "<PID>"

# macOS / Linux
lsof -nP -iTCP:10808 -sTCP:LISTEN

Once you have found the process, end it, or change the client's inbound port to another free one.

The full sequence after changing the port

  1. Change the inbound port in the client settings and save;
  2. Turn the "system proxy" switch off and on again so the new port is written to the system;
  3. Check in system settings that the proxy address and port match;
  4. Verify once with curl through the new port to confirm the chain works.

Common sources of port conflicts

A previous client process did not exit cleanly, another proxy application occupies the same port range, or a development tool or local service happens to listen on the same port. Before changing the port, identify who holds it — do not just pick a different number blindly.

08 / Symptom SevenClient startup failures and corrupted configuration

The symptoms are a double-click that does nothing, an immediate exit after launch, or a normal interface with a core that keeps restarting. First work out whether "the client interface won't start" or "the core process won't start" — the two call for different investigations.

Validate the configuration syntax first

# Xray core: validate the config only, do not start the service
xray run -test -config config.json

# V2Fly core
v2ray test -config config.json

Common errors and what they mean:

  • invalid character: there is an illegal character in the JSON, usually a trailing comma, a comment or a full-width quotation mark;
  • unexpected end of JSON input: a bracket or quote was not closed;
  • unknown field: the field name is misspelled, or the current core does not support that field.

Comments and trailing commas in a configuration both cause parsing to fail, and copying config snippets from elsewhere is the most common way to bring them in.

The core keeps restarting

The interface says running, but the log shows the core process starting and exiting repeatedly — usually a failed configuration validation or a port conflict. Set the log level to debug, look at the last line before each exit, then follow the procedures in Chapter 03 and Chapter 07.

Permissions and paths

  • When the installation directory sits under a system-protected directory, writing the configuration needs administrator rights; you can move the data directory into your user directory instead;
  • When the path contains special characters or is very deep, some system components fail to read it;
  • After moving the configuration file, the old path recorded by the client no longer works.

Security software blocking

Some security software flags the proxy core as a risky program and blocks it silently. The typical sign is a process that disappears a few seconds after launch, while running the same configuration by hand from the command line works fine. The fix is to add an exception for that directory in the security software, or try a different installation directory. The first-time installation flow on Windows and its common pitfalls are covered step by step in Installing v2rayN on Windows.

Configuration backup and restore

Export the configuration before you change it. When startup problems appear, use the reset function to return to the default configuration and then restore items one by one — that pinpoints which configuration item caused the problem. Importing servers by hand is safer than restoring the whole configuration directory and easier to roll back.

When it crashesCommon causeAction
Nothing happens on double-clickSecurity software blocking, insufficient permissionsAdd an exception or run once as administrator
Exits immediately after launchConfiguration syntax errorValidate the configuration with -test and fix the JSON
Interface fine, core keeps restartingPort conflict or unsupported fieldChange the port, check the fields the core supports
Appears only after a config changeThe newly added configuration item is wrongRoll back to the last working configuration

09 / Symptom EightAndroid-specific troubleshooting

Android runs v2rayNG (Xray core) and v2flyNG (v2fly core). They work differently from the desktop: the phone captures traffic in VPN mode and there is no "system proxy" layer, so some desktop troubleshooting steps do not apply on mobile — and vice versa.

Differences between the two clients

Itemv2rayNGv2flyNG
CoreXrayv2fly
PositioningFirst choice, faster support for new protocol parametersAlternative, consistent with the v2fly ecosystem
Configuration scopeSupports Xray extension fieldsLimited to what v2fly supports

The same share link imports into both, but a few newer protocol parameters only take effect on the Xray core. When something "imports but won't connect", try the other client once — it quickly tells you whether the problem is the parameters or the client. Both installers are in the Android section of the download page.

Common reasons it won't connect

  • VPN authorisation dialog not confirmed: the system shows an authorisation dialog on first connect and you must allow the VPN connection;
  • Another VPN app is already running: only one VPN tunnel is allowed at a time;
  • Battery policy: the app is killed in the background by the system, shown by the notification icon disappearing and the connection dropping;
  • Per-app proxy: only some apps are ticked, and unticked apps do not go through the proxy.

Subscriptions and server management

When a subscription update fails on the phone, switch networks and try again: swap mobile data and Wi-Fi once. A change in server order after an update is normal — go by the subscription content. Subscription URLs carry a token, so do not post screenshots in public. Server list management matches the desktop, and the subscription failure flow in Chapter 04 applies directly.

Logs and self-checks

The log page in v2rayNG shows the core output, and the approach matches the desktop: look at the error line for the timestamp first, then tell apart timeout, authentication and DNS problems. There is no command-line environment on mobile, so verification relies mainly on switching servers and switching networks for comparison.

CheckDesktopAndroid
Traffic captureSystem proxy or TUN modeVPN mode, no system proxy layer
Port checksnetstat / lsof for inbound portsNot applicable, assigned by the system
Background survivalSuspended when the system sleepsAffected by battery policy, needs whitelisting
Verificationcurl from the command line through the local proxySwitch servers and networks for comparison

Do not run two proxy apps at the same time

Android allows only one VPN tunnel, and the one started later takes over from the earlier one — which looks like "the first app disconnected for no reason". Before troubleshooting, confirm that only one proxy app is running on the system.

If none of the nine chapters covers your case, sum the situation up in one sentence: what you did, when it happened, and what the last line of the log says. The FAQ page collects more detailed Q&A by topic, and the glossary page helps you check what the terms in the log mean.