Tencent/VasSonic · error · IllegalArgumentException
Attempt to verify non-SSL socket
Error message
Attempt to verify non-SSL socket
What it means
SonicSniSSLSocketFactory.verifyHostname() performs SNI-safe hostname verification by starting the TLS handshake itself. It throws IllegalArgumentException when the socket passed is not an SSLSocket, since verification is meaningless for plain sockets.
Solutions
- Ensure the factory is only used for HTTPS connections; don't apply it to plain sockets
- Check that the delegate SSLSocketFactory creates real SSL sockets (not a mock/fallback)
- Guard call sites: only call verifyHostname on sockets where socket instanceof SSLSocket
- If supporting both schemes, branch: verify hostname only when the scheme is https
Example fix
// before
SonicSniSSLSocketFactory.verifyHostname(socket, host); // throws for plain sockets
// after
if (socket instanceof SSLSocket) {
SonicSniSSLSocketFactory.verifyHostname(socket, host);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!(socket instanceof SSLSocket)) {
throw new IllegalArgumentException("verifyHostname requires an SSLSocket");
} Type guard
// Java
static boolean isSsl(Socket s) {
return s instanceof SSLSocket;
} Try / catch
try {
SonicSniSSLSocketFactory.verifyHostname(socket, host);
} catch (IllegalArgumentException e) {
// socket was not SSL: skip verification or fail the connection
} Prevention
- Use the SNI factory only for HTTPS connections
- Verify custom socket-factory delegates actually produce SSLSockets
- Assert the scheme is https before hostname verification
When it happens
Trigger: Calling verifyHostname(socket, hostname) with a plain socket, typically when createSocket() on the factory returned a non-SSL socket because the underlying SSLSocketFactory could not create an SSL connection (e.g. plain-HTTP connection reused through the factory).
Common situations: Wiring the SNI socket factory into a connection that falls back to plain HTTP; a custom SSLSocketFactory delegate returning non-SSL sockets; using the factory with an http:// URL by mistake.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Cannot verify SSL socket without session
- SonicDBHelper::createInstance() needs to be called before…
- SonicEngine::createInstance() needs to be called before…
- SonicRuntime context con not be null!
- This isn't a hierarchical URI.
AI-assisted analysis of Tencent/VasSonic@59936beff6 (2026-09-08).
Data as JSON: /api/errors/becf25f3cf38ee16.
Report an issue: GitHub.
Appendix: source
Thrown at sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicSniSSLSocketFactory.java:177
/**
* Verify the hostname of the certificate used by the other end of a
* connected socket. You MUST call this if you did not supply a hostname
* to {@link #createSocket()}. It is harmless to call this method
* redundantly if the hostname has already been verified.
*
* <p>Wildcard certificates are allowed to verify any matching hostname,
* so "foo.bar.example.com" is verified if the peer has a certificate
* for "*.example.com".
*
* @param socket An SSL socket which has been connected to a server
* @param hostname The expected hostname of the remote server
* @throws IOException if something goes wrong handshaking with the server
* @throws SSLPeerUnverifiedException if the server cannot prove its identity
*
*/
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)