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.
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.
- Save the current configuration and note the system time, selected node, and active core.
- Open the client's log viewer and make sure it shows core output, not just subscription update messages.
- Pause network activity in other apps, access a fixed destination, and reproduce the failure once.
- 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.
| Level | What it records | When to use it |
|---|---|---|
debug | Debug details and more severe messages | Briefly reproducing complex connection issues |
info | General runtime information, warnings, and errors | Monitoring startup, connections, and request handling |
warning | Warnings and errors | Everyday use with less routine output |
error | Errors | Only explicit failure messages |
none | Disable error log output | Not 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.
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"
- Nothing is listening: fix the core startup error first, then test with a browser or terminal.
- A listener is present, but the protocol doesn't match: an HTTP proxy address cannot be pointed at a SOCKS-only port.
- After changing the port to 10810: apps still pointing to 10808 will keep failing. Check the system proxy and terminal environment variables separately.
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.
- Check whether the node's
addressis a domain or an IP address, and confirm that its port matches the server. - Run a system DNS lookup for the domain to check whether resolution works on the local machine. On Windows, use
nslookupfollowed by the actual node domain. - 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. - 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 symptom | Fields to check first | What to verify |
|---|---|---|
| Bind error during startup | inbounds[].listen、inbounds[].port | Whether the address is local and the port is already in use |
| App cannot connect to the local inbound | inbounds[].protocol | Whether the app's HTTP or SOCKS setting matches the listener |
| Remote connection refused or dial timed out | Address and port in outbounds[].settings | Node details, remote listener, and network path |
| Domain name resolution failed | dns.servers and related resolution policies | DNS records, resolver reachability, and the path taken by DNS traffic |
| Certificate name or TLS handshake error | streamSettings、tlsSettings.serverName | Security type, SNI, certificate, and system time |
| Request routed to the wrong outbound | routing.rules[].outboundTag、outbounds[].tag | Rule 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.
- Before changing anything: Back up the configuration and keep the original error text and the time it occurred.
- Make the change: Change only the setting directly related to the failed stage. If the node is managed by a subscription, remember that an update may overwrite manual changes.
- Verify: Restart the core to apply the configuration, then retest with the same app and destination.
- Wrap up: Once access is restored, lower the log level and delete diagnostic files you no longer need.
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.