At a glance

For Android users whose connection stops immediately after tapping Connect or whose logs show repeated errors. First identify whether the issue occurs while loading the configuration, starting a local listener, or connecting to the server, then follow the error chain to the specific field. This guide covers log collection, common error messages, and configuration snippets. Change one thing at a time so a traceable issue doesn’t turn into several.

First, tell whether the core failed to start or started but couldn’t connect

v2rayNG is an Android client, and this guide focuses on logs from the Xray core it uses. Seeing a VPN icon after tapping Connect only indicates that Android has established the corresponding service state; it does not confirm that the node is working. Likewise, a webpage failing to load doesn’t necessarily mean the core failed to start. If the local listener is up and a timeout appears only when you first visit a site, investigate the connection to the remote server.

StageLog clueCheck first
Loading configurationfailed to read config files、invalid characterJSON syntax and configuration source
Building configurationfailed to build followed by the specific field errorProtocol name, field type, and core support
Starting local listenerbind: address already in useListen address and local port
Connecting to remote serveri/o timeout、connection refusedServer address, remote port, and route
Security or transport handshakex509:、bad handshakeCertificate hostname, TLS, and transport settings

A single log entry may link several causes with >. “Startup failed” at the beginning describes the outcome; details about a character, port, or certificate later in the chain are more likely to point to the root cause. Keep the entire error chain, then work backward from the end to identify the specific item. Don’t rely on just the most prominent red line.

Capture a clean log, starting when you tap Connect

Keep your current node and custom configuration before collecting logs. Menu names and locations can vary slightly between v2rayNG versions. A common route is Logs in the menu at the top left of the main screen; set the log level under Settings. If you can’t find an option with the same name, follow the interface in your installed version rather than copying the Preferences steps from desktop v2rayN.

  1. Record your setup

    In Android Settings → Apps → v2rayNG, note the client version from App info. Also record your Android version, node protocol, and whether you use a custom configuration. Include the core version if it appears in the logs.

  2. Stop the connection

    Return to the v2rayNG main screen and tap the connection button to stop the service. Temporarily stop other VPN apps to avoid interference from Android switching VPN services.

  3. Set the log level

    Go to Settings → Log level and select info. If that doesn’t provide enough detail, temporarily switch to debug. If you use a complete custom JSON configuration, also check log.loglevel in it.

  4. Reproduce the issue once

    Open Logs and clear the old entries, then return to the main screen and connect once. If the service stays running, visit a webpage, then return to the logs and review entries from that time.

  5. Keep the surrounding context

    Copy the complete log entries from before and after the first failure. Before sharing, redact subscription URLs, UUIDs, passwords, and server details, but keep field names, error order, and the relationships between references to the same address.

debug provides detailed output, info records routine activity, warning flags a potential issue, and error indicates that an operation failed. These levels don’t rate how good a node is. An error from one request doesn’t mean the whole core has stopped, and no visible errors may simply mean the log level is too high. When you’re done troubleshooting, restore the original level to avoid unnecessary logging.

JSON syntax errors: fix the format before checking the node

If a custom configuration fails right after import, start by checking for parsing errors. JSON property names and strings must use straight double quotes. Curly quotes, missing commas, and trailing commas can all cause errors. The examples use strict JSON for portability and troubleshooting; they don’t rely on any loader-specific support for comments.

Error: invalid character '}' looking for beginning of object key string

Cause: There’s a comma after the object’s last property. The parser expects another property name but encounters a closing brace.

Fix: Check the property immediately before the reported location and remove the trailing comma. Check adjacent objects too; don’t simply delete the closing brace.

Error: unexpected end of JSON input

Cause: The content ends unexpectedly, often because the configuration wasn’t copied in full, a closing bracket is missing, or a string isn’t closed.

Fix: Import the original configuration again. Check that the final quotes, square brackets, and curly braces are paired correctly; don’t add closing brackets repeatedly by guesswork.

In the snippet below, there’s an extra comma after "warning". The error may point to the closing brace on the next line rather than the comma itself, so check the line above the reported location.

{
  "log": {
    "loglevel": "warning",
  }
}

Here’s the corrected snippet. It shows only how to write log; it isn’t a complete, standalone configuration. Replace the corresponding object in the original file, and don’t overwrite its existing inbounds, outbounds, or routing rules.

{
  "log": {
    "loglevel": "warning"
  }
}

Port conflicts: check the local listener, not the server port

A bind error occurs while starting a local listener. That’s a different issue from failing to connect to a remote server. The numbers below are examples for troubleshooting, not defaults for every v2rayNG installation. Check the local ports shown in Settings and the actual error in your logs.

10808
Example: local SOCKS listening port
10809
Example: local HTTP listening port
443
Example: remote server port for a node

Error: bind: address already in use

Cause: A process is already using the listening port on the target address. Two inbounds in a custom configuration may also be trying to bind to the same port.

Fix: Stop the relevant service and try again. If it still fails, check inbounds in the complete configuration and verify the listen, port, and protocol for each entry.

If the log specifically says that binding 127.0.0.1:10808 failed, try changing the local SOCKS port to an unused port such as 10818, then restart. Update any other apps that rely on that SOCKS port as well. Changing only the remote port on the node edit screen won’t free the local listener and may break a node setting that was already correct.

Bottom line: identify which address is involved before changing a port

If the error mentions 127.0.0.1 and bind, check the phone’s local listener first. If it shows a server address and a connection timeout, investigate the remote connection. Don’t change both at once.

Field names and core support: valid JSON isn’t enough

A successful JSON parse only confirms that the format is valid; it doesn’t mean Xray accepts every value. For example, network in streamSettings must use a transport identifier supported by the core. WebSocket uses ws, not websocket. A protocol name shown in the client interface may also differ from the string used in the configuration.

The example below shows the structure for WebSocket and TLS and is intended only to help verify field placement. The domain and path are examples; in practice, they must match the server settings. This object isn’t a complete outbound configuration.

{
  "streamSettings": {
    "network": "ws",
    "security": "tls",
    "tlsSettings": {
      "serverName": "example.com"
    },
    "wsSettings": {
      "path": "/tunnel",
      "headers": {
        "Host": "example.com"
      }
    }
  }
}

Keep in mind that unknown fields don’t always cause startup errors. Some loading processes ignore them, so the settings you intended to enable may have no effect. Conversely, a newer parameter may fail during configuration building if the core doesn’t support it. Before updating, note your client and core versions and keep the original configuration. After updating, test the original node first; don’t change the protocol and the entire routing setup at the same time.

Transport and certificate errors: usually after startup

If the core has already started a local listener and these errors appear only when you visit a webpage, stop looking for a JSON comma. First verify the node address and remote port, then check TLS, security, and transport settings. These are common error snippets; the full prefixes and surrounding text vary by core version.

Error: websocket: bad handshake

Cause: The WebSocket handshake didn’t receive the expected response. Common causes include a mismatched path, Host, remote port, or reverse proxy forwarding rule.

Fix: Compare path, Host, and the TLS setting with the details provided by the server. Don’t change the UUID just because the error mentions a handshake.

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

Cause: The certificate is outside its validity period. The server certificate may have expired, or the phone’s clock may be wrong.

Fix: In Android’s Date & time settings, turn on automatic date and time and verify the current date. If the date is correct and the error persists, ask the service provider to check the certificate.

Error: connection refused

Cause: The connection was actively refused. There may be no service listening on the target port, or an intermediary may have returned a rejection.

Fix: Check the target address and port shown in the error, then confirm that the server is listening. Changing the local SOCKS port won’t fix a refusal from the remote server.

Error: i/o timeout

Cause: A network operation didn’t complete in time. This message alone doesn’t tell you whether the issue is DNS, the network route, or the server.

Fix: Keep the operation immediately before the error and distinguish DNS resolution from dialing and the handshake. With the same configuration, compare the result over Wi-Fi and mobile data.

TLS serverName is used for server-name-related handshakes and certificate verification; the WebSocket Host is used for HTTP requests. They may match, or differ depending on how the server is set up. Don’t disable certificate verification just to make the error disappear; that can hide a hostname or certificate configuration issue.

Retest after the fix: keep a record and avoid random changes

After making one change, stop the service, clear the old logs, and connect again. First confirm that the core keeps running, then make one webpage request and check for new errors from that request. If a subscription update regenerates the node, manual changes may be overwritten. Record why you made the change instead of just noting that it works now.

The logs are full of warnings. Do I need to fix every one?

No. Not every warning means startup failed. Find the error chain for the current connection by timestamp, then check whether the service stopped or the request failed. Address only warnings related to the problem you’re seeing, so you don’t introduce extra variables.

The subscription imported successfully. Why won’t it start?

A successful import only means the client accepted the subscription data; it doesn’t guarantee that the current core supports every generated parameter. Select one node and reproduce the issue, check the logs for protocol or field errors, then compare your client version with the node’s requirements.

How do I find the error if the JSON log has no line number?

For a custom configuration, format a copy in a local editor and search for the field mentioned in the log. For a regular node configuration, check the corresponding settings in the node editor. Don’t rewrite the entire configuration just to find a line number.

Would reinstalling the client be faster?

Back up your configuration and copy the logs first. Reinstalling won’t automatically fix a port conflict, a server certificate issue, or incorrect subscription parameters. Consider clearing app data or reinstalling only after confirming that the app data is faulty and preserving what you’ll need to restore.

Keep a short troubleshooting record: client version, core details, the first complete error, the one change you made, and the retest result. If the same error comes back, you’ll be able to tell whether the original issue returned or the failure has moved to a new stage.