Tencent/VasSonic · error · SSLPeerUnverifiedException

Cannot verify hostname:

Error message

Cannot verify hostname: 

What it means

After obtaining the SSLSession, verifyHostname() runs the default HttpsURLConnection hostname verifier against it. If verification fails (certificate CN/SAN doesn't match the requested hostname), it throws SSLPeerUnverifiedException — protecting against MITM and hostname mismatches.

Solutions

  1. Access the server using a hostname that exactly matches a SAN entry in its certificate
  2. Fix the server certificate to include the hostname (add SAN entries) and redeploy
  3. Remove IP-based URLs or custom host mappings that bypass proper hostname matching
  4. If intentional (e.g. test environments), install a custom HostnameVerifier — but never disable verification in production

Example fix

// before
URL url = new URL("https://10.0.0.5/api"); // cert has no IP SAN -> throws
// after
URL url = new URL("https://api.example.com/api"); // matches cert SAN
Defensive patterns

Strategy: try-catch

Validate before calling

Certificate[] certs = ssl.getSession().getPeerCertificates();
// check that host matches a SAN entry before connecting
// e.g. hostname must equal one of the dNSName SANs in certs[0]

Try / catch

try {
  SonicSniSSLSocketFactory.verifyHostname(socket, host);
} catch (SSLPeerUnverifiedException e) {
  // hostname mismatch: do NOT proceed; alert or use the cert-matching hostname
}

Prevention

When it happens

Trigger: The server presents a valid certificate that does not match the hostname used in the request — connecting by IP address, a hostname not in the cert's SAN, an internal hostname fronted by a generic cert, or DNS pointing to a different server.

Common situations: Hitting a server via its IP or an alias not listed in the certificate; expired/reissued certs missing the old SAN entries; proxies/gateways serving the wrong cert; testing against a staging server using production certs.

Related errors


AI-assisted analysis of Tencent/VasSonic@59936beff6 (2026-09-08). Data as JSON: /api/errors/e364fa1c817abc9a. Report an issue: GitHub.

Appendix: source

Thrown at sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSniSSLSocketFactory.java:192

     */
    public static void verifyHostname(Socket socket, String hostname) throws IOException {
        if (!(socket instanceof SSLSocket)) {
            throw new IllegalArgumentException("Attempt to verify non-SSL socket");
        }

        // The code at the start of OpenSSLSocketImpl.startHandshake()
        // ensures that the call is idempotent, so we can safely call it.
        SSLSocket ssl = (SSLSocket) socket;
        ssl.startHandshake();

        SSLSession session = ssl.getSession();
        if (session == null) {
            throw new SSLException("Cannot verify SSL socket without session");
        }

        if (!HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session)) {
            SonicUtils.log(TAG, Log.ERROR, "sonic SSL error:Cannot verify hostname" + hostname + ")!");
            throw new SSLPeerUnverifiedException("Cannot verify hostname: " + hostname);
        }
    }
}

View on GitHub (pinned to 59936beff6)