{"record":{"id":"82d5b20016bfb3fa","repo":"grpc/grpc-java","slug":"socket-is-not-a-type-of-sslsocket","errorCode":null,"errorMessage":"socket is not a type of SSLSocket","messagePattern":"socket is not a type of SSLSocket","errorType":"exception","errorClass":"CertificateException","httpStatus":null,"severity":"error","filePath":"util/src/main/java/io/grpc/util/AdvancedTlsX509TrustManager.java","lineNumber":177,"sourceCode":"    if (sslEngine == null && socket == null) {\n      throw new CertificateException(NOT_ENOUGH_INFO_MESSAGE);\n    }\n    if (this.verification != Verification.INSECURELY_SKIP_ALL_VERIFICATION) {\n      X509ExtendedTrustManager currentDelegateManager = this.delegateManager;\n      if (currentDelegateManager == null) {\n        throw new CertificateException(\"No trust roots configured\");\n      }\n      if (checkingServer) {\n        String algorithm = this.verification == Verification.CERTIFICATE_AND_HOST_NAME_VERIFICATION\n            ? \"HTTPS\" : \"\";\n        if (sslEngine != null) {\n          SSLParameters sslParams = sslEngine.getSSLParameters();\n          sslParams.setEndpointIdentificationAlgorithm(algorithm);\n          sslEngine.setSSLParameters(sslParams);\n          currentDelegateManager.checkServerTrusted(chain, authType, sslEngine);\n        } else {\n          if (!(socket instanceof SSLSocket)) {\n            throw new CertificateException(\"socket is not a type of SSLSocket\");\n          }\n          SSLSocket sslSocket = (SSLSocket)socket;\n          SSLParameters sslParams = sslSocket.getSSLParameters();\n          sslParams.setEndpointIdentificationAlgorithm(algorithm);\n          sslSocket.setSSLParameters(sslParams);\n          currentDelegateManager.checkServerTrusted(chain, authType, sslSocket);\n        }\n      } else {\n        if (sslEngine != null) {\n          currentDelegateManager.checkClientTrusted(chain, authType, sslEngine);\n        } else {\n          currentDelegateManager.checkClientTrusted(chain, authType, socket);\n        }\n      }\n    }\n    // Perform the additional peer cert check.\n    if (socketAndEnginePeerVerifier != null) {\n      if (sslEngine != null) {","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/util/src/main/java/io/grpc/util/AdvancedTlsX509TrustManager.java#L159-L195","documentation":"AdvancedTlsX509TrustManager performs hostname verification by configuring endpoint identification on the TLS peer. When the transport is not an SSLSocket (and not an SSLEngine, which is handled in the other branch), the manager cannot set the endpoint identification algorithm and throws this CertificateException. It guards against being handed an unexpected socket implementation that cannot support hostname verification.","triggerScenarios":"checkClientTrusted or checkServerTrusted is invoked (via checkTrusted) with a Socket parameter that is not an javax.net.ssl.SSLSocket — e.g. a plaintext socket or a custom/wrapped socket implementation — while the trust manager is installed in an SSLContext used for that connection.","commonSituations":"Using AdvancedTlsX509TrustManager with a non-TLS socket or a socket wrapped by a proxying/interception layer (monitoring agents, custom SocketFactory); misconfigured SSLContext where the trust manager is applied to non-SSL transports; library versions where the connection provides a raw socket instead of an SSL socket.","solutions":["Ensure the connection actually uses TLS so the socket passed to the trust manager is an SSLSocket (use an SSLSocketFactory built from an SSLContext configured with this trust manager)","If you wrap or proxy sockets, unwrap to the underlying SSLSocket before it reaches the SSLEngine/SSLSocket verification path","Prefer the checkServerTrusted/checkClientTrusted overloads that accept an SSLEngine, which are used by modern TLS stacks (e.g. via X509ExtendedTrustManager) and avoid the socket branch","Verify you are not registering this trust manager in a non-TLS context such as plain HTTP or a custom protocol"],"exampleFix":"// before\nSocket socket = new Socket(host, port);\n// TLS check on a plain socket fails\n// after\nSSLContext sslContext = SSLContext.getInstance(\"TLS\");\nsslContext.init(null, new TrustManager[]{advancedTlsX509TrustManager}, null);\nSSLSocketFactory factory = sslContext.getSocketFactory();\nSSLSocket socket = (SSLSocket) factory.createSocket(host, port);","handlingStrategy":"type-guard","validationCode":"if (socket instanceof SSLSocket) {\n  // safe to proceed with AdvancedTlsX509TrustManager\n} else {\n  throw new IllegalArgumentException(\"Transport must be TLS: got \" + socket.getClass().getName());\n}","typeGuard":"static boolean isTlsSocket(Socket socket) {\n  return socket instanceof SSLSocket;\n}","tryCatchPattern":"try {\n  sslContext.init(null, new TrustManager[]{advancedTlsManager}, null);\n} catch (CertificateException e) {\n  if (e.getMessage().contains(\"socket is not a type of SSLSocket\")) {\n    throw new IllegalStateException(\"Non-TLS transport used with TLS trust manager\", e);\n  }\n  throw e;\n}","preventionTips":["Only install AdvancedTlsX509TrustManager in SSLContexts used for TLS connections","Prefer the SSLEngine-based trust-manager path (X509ExtendedTrustManager) used by modern stacks","Unwrap wrapped/proxied sockets to the underlying SSLSocket","Do not reuse a TLS-configured SSLContext for plaintext sockets"],"tags":["tls","ssl","certificate-verification","grpc"],"backgroundTag":"type-mismatch","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}