{"record":{"id":"d1dbfafdc258c4dc","repo":"Tencent/VasSonic","slug":"cannot-verify-ssl-socket-without-session","errorCode":null,"errorMessage":"Cannot verify SSL socket without session","messagePattern":"Cannot verify SSL socket without session","errorType":"exception","errorClass":"SSLException","httpStatus":null,"severity":"error","filePath":"sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSniSSLSocketFactory.java","lineNumber":187,"sourceCode":"     * @param socket An SSL socket which has been connected to a server\n     * @param hostname The expected hostname of the remote server\n     * @throws IOException if something goes wrong handshaking with the server\n     * @throws SSLPeerUnverifiedException if the server cannot prove its identity\n     *\n     */\n    public static void verifyHostname(Socket socket, String hostname) throws IOException {\n        if (!(socket instanceof SSLSocket)) {\n            throw new IllegalArgumentException(\"Attempt to verify non-SSL socket\");\n        }\n\n        // The code at the start of OpenSSLSocketImpl.startHandshake()\n        // ensures that the call is idempotent, so we can safely call it.\n        SSLSocket ssl = (SSLSocket) socket;\n        ssl.startHandshake();\n\n        SSLSession session = ssl.getSession();\n        if (session == null) {\n            throw new SSLException(\"Cannot verify SSL socket without session\");\n        }\n\n        if (!HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session)) {\n            SonicUtils.log(TAG, Log.ERROR, \"sonic SSL error:Cannot verify hostname\" + hostname + \")!\");\n            throw new SSLPeerUnverifiedException(\"Cannot verify hostname: \" + hostname);\n        }\n    }\n}\n","sourceCodeStart":169,"sourceCodeEnd":196,"githubUrl":"https://github.com/Tencent/VasSonic/blob/59936beff656d4b5718ff6444d6c5e001a2c5231/sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSniSSLSocketFactory.java#L169-L196","documentation":"After starting the handshake for SNI hostname verification, verifyHostname() fetches the SSLSession and throws SSLException if the session is null — without a session there are peer certificates to verify against.","triggerScenarios":"ssl.getSession() returns null after startHandshake(), which happens when the TLS handshake failed or was aborted before a session was established (e.g. handshake interrupted, SSL library error swallowed, or a non-standard SSLSocket implementation).","commonSituations":"Servers abruptly closing the connection during handshake; TLS version/cipher mismatch with the server; custom SSLSocket implementations that don't populate the session; low-level network errors during the handshake on flaky mobile networks.","solutions":["Retry the request; a null session usually indicates a transient handshake failure on mobile networks","Check server TLS compatibility (supported protocol versions/ciphers) and enable TLSv1.2 explicitly via ssl.setEnabledProtocols","Verify no custom SSL implementation overrides getSession() incorrectly","Log and surface the underlying handshake exception from startHandshake() to diagnose the root cause"],"exampleFix":"// before\nssl.startHandshake();\nSonicSniSSLSocketFactory.verifyHostname(socket, host);\n// after\nssl.setEnabledProtocols(new String[]{\"TLSv1.2\"});\ntry {\n  ssl.startHandshake();\n} catch (IOException e) {\n  throw new SSLException(\"Handshake failed for \" + host, e);\n}","handlingStrategy":"retry","validationCode":"try { ssl.startHandshake(); } catch (IOException e) {\n  throw new SSLException(\"Handshake failed, session unavailable for \" + host, e);\n} // only proceed if handshake succeeded","typeGuard":"// Java\nstatic boolean hasSession(SSLSocket ssl) {\n  return ssl.getSession() != null;\n}","tryCatchPattern":"try {\n  SonicSniSSLSocketFactory.verifyHostname(socket, host);\n} catch (SSLException e) {\n  // transient handshake failure: retry request or surface a network error\n}","preventionTips":["Enable TLSv1.2+ explicitly on sockets for older Android versions","Retry once on handshake failures (common on flaky mobile networks)","Keep the platform SSL provider updated; avoid exotic custom SSLSocket impls"],"tags":["ssl","tls-handshake","android"],"backgroundTag":"http-request-failed","analyzedSha":"59936beff656d4b5718ff6444d6c5e001a2c5231","analyzedAt":"2026-09-08T10:27:05.448Z","contentChangedAt":"2026-09-08T10:27:05.448Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}