TLS Handshake Failures and Certificate Errors: Three Key Checks for System Time, SNI, and allowInsecure

A certificate error cannot be diagnosed by switching nodes repeatedly. Check the system clock first, then compare SNI with the node address, and finally verify the server’s certificate chain to pinpoint whether the issue is on the client or server.

Quick overview

This guide is for v2rayN, v2rayNG, and v2flyNG users who see certificate, x509, handshake, or unknown authority errors. Preserve the original logs, check the system time and time zone, verify SNI, then check the certificate validity period and chain. Use allowInsecure only briefly for diagnosis, never as a permanent fix.

Where the TLS error occurs

After TLS is enabled for a VMess or VLESS node, the client does not immediately send proxy data upon connecting to the server. It first establishes a TCP connection and sends a TLS ClientHello, which may include SNI, supported TLS versions, and ALPN. The server then returns its certificate chain and negotiates session keys. Only after the handshake succeeds do protocol authentication and data transfer enter the encrypted channel.

Resolve node addressEstablish TCPSend SNIValidate certificateEnter proxy protocol

So, “the node won’t connect” does not necessarily mean the node account is invalid. If the logs show an expired certificate, hostname mismatch, or unknown certificate authority, the failure usually occurs before the VMess user ID, VLESS UUID, transport path, and routing rules are involved. Changing subscription groups, the system proxy port, or routing rules will not usually fix a certificate error.

During troubleshooting, open the client core logs instead of relying only on a browser page. In v2rayN, review recent connections in the log area at the bottom of the main window, and check Settings → Parameter Settings to ensure the log level is not set too low. In v2rayNG and v2flyNG, open the runtime log page for the relevant configuration and record the first TLS or x509 error exactly as shown.

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

Cause and fix: The local clock is outside the certificate’s validity period, or the server certificate has actually expired. Sync the system time first, then compare the current time and the certificate’s validity dates in the logs.

Error: x509: certificate is valid for another.example, not node.example

Cause and fix: The certificate name returned by the server does not match the name being verified by the client. Check the node’s SNI; do not enter the subscription label, WebSocket path, or IP address in this field.

Error: x509: certificate signed by unknown authority

Cause and fix: The certificate chain is missing an intermediate certificate, or the certificate is not trusted by the system. Update the system certificate environment; if the issue affects multiple devices, the server should provide the complete chain.

Error: remote error: tls: handshake failure

Cause and fix: The server actively rejected the handshake, commonly because SNI, the TLS version, or ALPN does not match. Check the original subscription parameters first, then review the server’s listener configuration.

Step 1: Check the system time and time zone

TLS certificates contain two time boundaries: Not Before and Not After. The client uses the device’s current time to determine whether a certificate is valid or expired. If the clock is months ahead, a valid certificate may appear expired; if it is months behind, the certificate may appear not yet valid. The time zone does not change absolute time, but an incorrect time zone combined with a manually set clock often causes a real time offset.

±60 seconds
Recommended clock drift
443
Common TLS server ports
TLS 1.2+
Typical compatibility range
10808
Common local SOCKS port in v2rayN

On Windows, enable automatic time and automatic time-zone settings, then run an immediate sync. On a Linux desktop, check the system time status and confirm that the NTP service is synchronized. On Android, enable network-provided date, time, and time zone. After correcting the clock, fully stop and restart the client core so it does not reuse a failed connection state.

  1. Save the original logs

    Disconnect from the current node, clear the logs, reconnect once, and save the first x509 or TLS error with its timestamp. Do not keep only later timeout messages.

  2. Check the current time

    Compare the device date, minutes, and time zone with a trusted system time source. Keep the difference within 60 seconds where possible, and check that the clock was not set manually.

  3. Synchronize the time

    Enable automatic system synchronization. On Linux, run timedatectl status and confirm that the system clock is synchronized and the time zone is correct.

  4. Restart the client core

    In v2rayN, stop the service first and then start it again. On Android clients, disconnect the current configuration, end the connection, and reconnect to avoid reusing the old session.

  5. Compare the retest results

    If the not yet valid error disappears, the local clock was the root cause. If the same certificate expiration date still appears, continue checking whether the certificate has actually expired.

Step 2: Check SNI against the node address

SNI is the server name sent in the TLS ClientHello. A single IP address may host multiple sites, so the server uses SNI to choose the certificate and virtual host. A node’s connection address can be a domain or an IP, but the certificate name being verified usually must be a domain listed in the certificate. Do not guess it from the node label.

For example, the client may connect to an entry-point IP while the certificate was issued to a domain. In that case, enter the domain in the serverName or SNI field. Conversely, if the node address is already the correct domain and the subscription explicitly provides an SNI, keep the subscription value. Copying a WebSocket Host, HTTP path, subscription name, or node label into SNI will cause a name mismatch.

Configuration item What it does Common mistake
Address Used for DNS resolution and establishing the TCP connection Entering a full URL with a protocol prefix or path
Port Specifies the server’s TLS listening port Entering the local port 10808 as the remote port
SNI / serverName Selects the server certificate and determines the name to verify Entering an IP address, node label, or transport path
Host Used in HTTP or WebSocket request headers Assuming Host must always match SNI
Path Specifies the WebSocket or HTTP transport path Blaming an incorrect path for a certificate name mismatch

In v2rayN, double-click the target node or right-click it and choose Edit Server. In the TLS section, check the serverName, SNI, or “Fake domain” field; the exact label varies by core and configuration type. Save the original subscription value before editing, then test only this setting. Do not change the port, transport, and UUID at the same time.

In v2rayNG or v2flyNG, disconnect first, then open the edit control beside the configuration and find the server name or fake domain under TLS security settings. If the configuration comes from a subscription, manual changes may be overwritten at the next update. Once the correct value is confirmed, ask the subscription provider to fix the source configuration.

Error: certificate is valid for example.net, not 203.0.113.10

Cause and fix: The client is validating the certificate against an IP address. Enter the certificate domain explicitly provided by the subscription as the SNI, keep the original connection address, and do not hide the issue by disabling verification.

Error: tls: unrecognized name

Cause and fix: The server does not accept the current SNI. Restore the original serverName from the subscription. If multiple clients fail, check the server’s virtual hosts and TLS listener configuration.

Step 3: Check for an expired or incomplete certificate chain

Once the system time and SNI are correct, check which certificate the server actually returns. An expired certificate has a Not After date earlier than the current time. An incomplete chain commonly occurs when the server sends only the site certificate and omits required intermediate certificates. Both are server-side configuration issues; reimporting the subscription will not normally fix them.

In a Linux environment with OpenSSL installed, use the command below to inspect the certificate chain returned on port 443. After -connect, enter the actual connection domain and port; after -servername, enter the SNI required by the node. Keep both parameters in the test, or the result may come from a different default certificate.

openssl s_client -connect server.example:443 \
  -servername node.example \
  -showcerts

openssl s_client -connect server.example:443 \
  -servername node.example \
  -verify_return_error < /dev/null

In the output, subject is the current certificate subject, issuer is the issuer, and notBefore and notAfter define the validity period. If the last line shows Verify return code: 0 (ok), the current system trust environment can build a complete verification path. Code 10 usually indicates an expired certificate; codes 20 or 21 commonly mean the local issuer could not be obtained or the first certificate could not be verified.

What allowInsecure fixes—and what it risks

The purpose of allowInsecure is to let the client accept a server certificate that fails normal validation. It may temporarily allow expired, self-signed, name-mismatched, or untrusted certificates, but it does not repair the server certificate or automatically correct the SNI, address, port, or transport configuration.

TLS data remains encrypted when this option is enabled, but the client loses the key step that reliably confirms the server’s identity. If an attacker can interfere with the network connection, they may impersonate the target server with another certificate. Use this option only for brief diagnosis: if the connection immediately works, the certificate verification stage is implicated. Then disable it and fix the time, SNI, or server certificate chain.

Keep the failure logEnable temporarilyTest onceConfirm a verification failureDisable and fix

In v2rayN, edit the relevant server and look for allowInsecure or “Skip certificate verification” in the TLS section. In v2rayNG and v2flyNG, the TLS settings on the configuration edit page usually show “Allow insecure connections” or a similar label. Change it only for the node being tested; never apply it in bulk to every subscription configuration.

Identify the responsible side from the logs

An effective troubleshooting session changes only one variable at a time and records the first error before and after each change. If you reimport the subscription, switch cores, change SNI, enable allowInsecure, and change networks all at once, even a successful connection will not reveal the real cause. A later subscription update may bring the problem back.

Build a minimal test set: keep the same node, network, and client core, then sync the time, verify SNI, validate the certificate chain, and only then test allowInsecure briefly. Temporarily disable frequent automatic node switching so errors from other servers do not contaminate the logs.

Still seeing a certificate-expired error after syncing the time?

Check notAfter in the logs or OpenSSL output. If the expiration date is truly earlier than the current time, the server certificate is the problem. If the date seen by the client differs from the server’s published result, check whether the connection reached an old entry-point IP.

Should SNI contain the node address or Host?

Use the server name explicitly provided by the subscription. If none is provided, use the domain covered by the certificate in most cases; do not infer it from the node label alone. Host and SNI serve different purposes and should not be forced to match.

The connection works after enabling allowInsecure—what next?

Immediately save the logs from before and after enabling the option, then disable it. Use the specific error to check certificate validity, name matching, and the certificate chain. Do not leave a temporary diagnostic setting in the subscription.

Why didn’t updating the subscription fix the certificate error?

A subscription updates only the node parameters received by the client. If the server still sends an expired certificate or omits an intermediate certificate, updating again will not change the handshake result. The server must update and reload its certificate.

What if the handshake fails only on mobile data?

First compare DNS results on the mobile network and another network, then check whether the system time is being synchronized automatically by the network. If the certificate name changes or a different entry point is returned, save both sets of logs for comparison.

The final diagnosis can be reduced to three rules: fix time errors on the local device; correct SNI using the subscription and certificate domain; if multiple devices receive an expired certificate or incomplete chain, fix it on the server. Separating these cases prevents TLS handshake failures from being mistaken for port, UUID, subscription, or routing problems.

Download v2rayN Windows, macOS, Android, and Linux clients