At a glance

For users whose client starts but requests fail. First distinguish client logs, core error logs, and access logs, then check each layer in turn: local listeners, DNS, remote connections, TLS, and protocol authentication. An error is a clue, not a final diagnosis. Find the most specific underlying cause before deciding which field to change; this is usually more effective than repeatedly reinstalling the software.

1. Identify the log source, then reproduce the issue once

v2rayN is the client; V2Ray or Xray is the core that handles connections. Subscription download failures and errors saving interface settings are client-side events. Listener startup failures and proxy handshake errors usually come from the core. On Android, v2rayNG uses the Xray core, while v2flyNG uses the V2Fly core. Log wording varies across cores and versions, so searching for an exact full line may not find the answer.

Core logs include access logs and error logs. Access logs show whether a request reached an inbound, which destination it targeted, and which outbound was selected. Error logs show problems during startup and connection handling. An accepted message usually means only that the inbound accepted the request; it does not mean the remote connection succeeded or that the webpage was returned.

Local inbound Rule matching Outbound resolution Remote connection Security handshake Protocol authentication

Use this flow to identify the stage where troubleshooting should begin; not every connection resolves domain names in the same order. DNS may be queried during routing, or handled remotely. First find where the request failed rather than changing DNS, routing, and node settings all at once.

  1. Save the current configuration and note the system time, selected node, and active core.
  2. Open the client's log viewer and make sure it shows core output, not just subscription update messages.
  3. Pause network activity in other apps, access a fixed destination, and reproduce the failure once.
  4. Keep the continuous log lines from before and after the failure. Match them by time, destination address, and connection ID to follow the same request.

2. Choosing a loglevel: warning for daily use, debug for troubleshooting

log.loglevel controls how much detail appears in the error log. It does not affect connection speed or enable access logging. Use warning for everyday use to reduce noise; briefly switch to info or debug to reproduce an issue. Restore the previous level once the cause is found to limit log growth and avoid exposing more connection details than necessary.

LevelWhat it recordsWhen to use it
debugDebug details and more severe messagesBriefly reproducing complex connection issues
infoGeneral runtime information, warnings, and errorsMonitoring startup, connections, and request handling
warningWarnings and errorsEveryday use with less routine output
errorErrorsOnly explicit failure messages
noneDisable error log outputNot suitable while troubleshooting

This is a snippet of the top-level log object in a V2Ray-style configuration, not a complete, runnable config. When using a GUI client, adjust the log settings there first; the client may overwrite generated configuration files on the next launch. Whether output goes to a file or the console also depends on the log path and how the client captures output.

{
  "log": {
    "loglevel": "debug"
  }
}

3. Connection refused and port conflicts: check which end the address belongs to

connection refused means the connection was actively rejected. This commonly happens when no service is listening on the destination port or a firewall actively rejects the connection. Start by checking the IP and port in the error: if it points to 127.0.0.1, check the local listener; if it points to the node server, check the remote service. Confusing the two can lead you to change the node settings while the local proxy still cannot be reached.

Error: connect: connection refused

Cause: The destination actively rejected this TCP connection. This message alone does not mean the account is invalid.

Fix: Check the destination address and port in the same log line. For a local address, make sure the core is running; for a remote address, check the node port and whether the service is listening.

Error: bind: address already in use

Cause: The core cannot bind to the listener address, usually because another process is already using that address and port.

Fix: Identify the process using the port, close duplicate instances, or change the local listener port and update the application's proxy address to match.

The numbers below are examples of common configurations, not fixed defaults for the current version. Some configurations combine HTTP and SOCKS on a single mixed inbound. Always use the listener details shown by the client. A remote port of 443 does not, by itself, prove that the service uses TLS.

10808
Example local SOCKS port
10809
Example local HTTP port
443
Example remote TLS port

On Windows, use the command below to check these two local ports. The last column shows the PID; look for TCP entries in the LISTENING state. Then check the process name on Task Manager's Details tab. Don't terminate an unfamiliar process based on its port number alone.

netstat -ano | findstr ":10808"
netstat -ano | findstr ":10809"

4. Timeouts and DNS errors: look for the most specific cause

i/o timeout means a read or write took longer than allowed; context deadline exceeded means an operation passed its deadline. Neither one directly means the node is down. DNS queries, TCP connections, TLS handshakes, or waiting for a response can all time out. Follow the error chain to the most specific underlying error and identify the address and stage where the timeout occurred.

Error: dial tcp ...: i/o timeout

Cause: If the context identifies the TCP dial stage, the connection was not established before the deadline. Possible causes include routing issues, packet loss, filtering, or an unreachable remote host.

Fix: Check the remote address and port, then test on your current network and another available network. Avoid masking the problem by simply increasing the timeout.

Error: no such host

Cause: The domain name did not resolve to a usable result. The name may be misspelled, its DNS record may be missing, or the resolution path may be failing.

Fix: First determine whether the domain in the error is the node address or the requested destination, then check the relevant resolver and DNS records.

Error: failed to find an available destination

Cause: This is a high-level summary of an outbound selection or connection failure. It does not, by itself, indicate a DNS problem.

Fix: Read the nested cause that follows. A resolution error points to DNS; a dial timeout points to remote reachability; a refusal points to the listening service.

For example, if a browser request fails but the log shows only a DNS error for the node's domain, no connection to the node has been established yet. Don't start by changing routing rules for the destination website. Conversely, if the node is connected and only one destination domain fails, check that domain's resolution and routing results.

  1. Check whether the node's address is a domain or an IP address, and confirm that its port matches the server.
  2. Run a system DNS lookup for the domain to check whether resolution works on the local machine. On Windows, use nslookup followed by the actual node domain.
  3. A successful system lookup does not guarantee that the core's DNS lookup will work. Also check dns.servers, resolver reachability, and the relevant routing.
  4. Change one variable at a time and record the errors before and after each change. Otherwise, it is hard to tell which setting made a difference.

5. TLS handshake failures: check the clock, certificate name, and transport settings

A successful TCP connection only means the remote port is reachable. The TLS handshake can still fail because of the certificate, server name, or protocol negotiation. Check that streamSettings.security matches the server's requirements. For standard TLS, also check tlsSettings.serverName. The server address and certificate name may differ, but they must match the server's deployment.

Error: x509: certificate has expired or is not yet valid

Cause: The system clock is incorrect, or the server certificate is outside its validity period.

Fix: First correct the system date, time, and time zone. If the clock is correct, the server administrator should check the certificate renewal and deployment.

Error: x509: certificate signed by unknown authority

Cause: The client cannot validate the certificate chain to a trusted root certificate. The server may be missing part of its certificate chain, or there may be an issue with the local trust store.

Fix: Check the complete certificate chain and the system's trusted certificates. Do not make skipping verification your everyday workaround.

Error: remote error: tls: handshake failure

Cause: The remote server rejected the TLS handshake; this message alone does not identify the exact cause.

Fix: Check the SNI, TLS settings, and port against the server configuration. If needed, compare the error with the server logs from the same time.

Transport or authentication errors can still occur after TLS succeeds. The WebSocket path and request Host, as well as the gRPC serviceName, must match the server configuration. websocket: bad handshake commonly points to a path, Host, reverse-proxy forwarding, or transport mismatch—not necessarily a certificate problem.

6. Trace log messages to configuration fields by failure stage

Choose fields based on the stage that failed. If listener binding fails at startup, check the inbound first. If the remote connection fails, start with the outbound address. If a request takes the wrong route, check the routing tags. The examples below use common V2Ray-style JSON; the actual structure depends on the core and the configuration generated by the client.

Observed symptomFields to check firstWhat to verify
Bind error during startupinbounds[].listen、inbounds[].portWhether the address is local and the port is already in use
App cannot connect to the local inboundinbounds[].protocolWhether the app's HTTP or SOCKS setting matches the listener
Remote connection refused or dial timed outAddress and port in outbounds[].settingsNode details, remote listener, and network path
Domain name resolution faileddns.servers and related resolution policiesDNS records, resolver reachability, and the path taken by DNS traffic
Certificate name or TLS handshake errorstreamSettings、tlsSettings.serverNameSecurity type, SNI, certificate, and system time
Request routed to the wrong outboundrouting.rules[].outboundTag、outbounds[].tagRule order and whether the tags point to the correct outbounds

VMess, VLESS, Trojan, and Shadowsocks use different authentication fields. Check the UUID, password, or encryption method only once the request reaches protocol authentication; don't assume every error means the password is wrong. Repeated EOF messages only indicate that the connection closed while reading. Check whether this happened before the handshake or after data transfer began.

7. Log troubleshooting FAQs

The log is blank. Does that mean the request never reached the proxy?

First confirm that the core is running, the error log level is not none, and the current view actually shows core output. Error logs may remain empty when there are no errors. To check whether a request reached the proxy, temporarily view the access log and verify the app's proxy address against the active listener port.

The browser works, but the terminal keeps reporting connection failures. Why?

The terminal may not use the system proxy. Check that its proxy environment variables point to an active listener and use the correct protocol. For example, use http://127.0.0.1:10809 only if port 10809 is actually an HTTP inbound. If the log shows no matching request, first troubleshoot the path from the app to the local listener.

v2rayNG disconnects when the screen turns off, but there are no TLS errors. What should I check?

First check whether the Android VPN connection is still active and whether the client process was stopped. Then review the app's battery and background activity permissions. If the system has terminated the core, the log may simply stop; that is different from a remote certificate failure. After changing background restrictions, retest with the screen locked and note when the connection stops.

What should I remove before sharing debug logs?

Remove subscription URLs, UUIDs, passwords, access tokens, and any server addresses, destination domains, or personal paths you don't want to make public. Keep the core type, error keywords, port roles, and the order of surrounding lines. You can replace addresses with labels such as "node address" or "destination address"; don't share only a cropped screenshot of the final line.