{"record":{"id":"55d57ca79c212a63","repo":"grpc/grpc-java","slug":"socketfactory-socketfactory-did-not-produce-an-55d57c","errorCode":null,"errorMessage":"SocketFactory ${socketFactory} did not produce an SSLSocket: ${socket.getClass()}","messagePattern":"SocketFactory (.+?) did not produce an SSLSocket: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"okhttp/src/main/java/io/grpc/okhttp/TlsServerHandshakerSocketFactory.java","lineNumber":51,"sourceCode":" * TLS handshaker.\n */\nfinal class TlsServerHandshakerSocketFactory implements HandshakerSocketFactory {\n  private final PlaintextHandshakerSocketFactory delegate = new PlaintextHandshakerSocketFactory();\n  private final SSLSocketFactory socketFactory;\n  private final ConnectionSpec connectionSpec;\n\n  public TlsServerHandshakerSocketFactory(\n      SslSocketFactoryServerCredentials.ServerCredentials credentials) {\n    this.socketFactory = credentials.getFactory();\n    this.connectionSpec = credentials.getConnectionSpec();\n  }\n\n  @Override\n  public HandshakeResult handshake(Socket socket, Attributes attributes) throws IOException {\n    HandshakeResult result = delegate.handshake(socket, attributes);\n    socket = socketFactory.createSocket(result.socket, null, -1, true);\n    if (!(socket instanceof SSLSocket)) {\n      throw new IOException(\n          \"SocketFactory \" + socketFactory + \" did not produce an SSLSocket: \" + socket.getClass());\n    }\n    SSLSocket sslSocket = (SSLSocket) socket;\n    sslSocket.setUseClientMode(false);\n    connectionSpec.apply(sslSocket, false);\n    Protocol expectedProtocol = Protocol.HTTP_2;\n    String negotiatedProtocol = OkHttpProtocolNegotiator.get().negotiate(\n        sslSocket,\n        null,\n        connectionSpec.supportsTlsExtensions() ? Arrays.asList(expectedProtocol) : null);\n    if (!expectedProtocol.toString().equals(negotiatedProtocol)) {\n      throw new IOException(\"Expected NPN/ALPN \" + expectedProtocol + \": \" + negotiatedProtocol);\n    }\n    attributes = result.attributes.toBuilder()\n        .set(GrpcAttributes.ATTR_SECURITY_LEVEL, SecurityLevel.PRIVACY_AND_INTEGRITY)\n        .set(Grpc.TRANSPORT_ATTR_SSL_SESSION, sslSocket.getSession())\n        .build();\n    return new HandshakeResult(socket, attributes,","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/okhttp/src/main/java/io/grpc/okhttp/TlsServerHandshakerSocketFactory.java#L33-L69","documentation":"TlsServerHandshakerSocketFactory wraps a user-supplied SocketFactory: after the delegate handshake, it layers TLS by calling socketFactory.createSocket(...). The result must be an SSLSocket; otherwise it throws IOException 'SocketFactory <f> did not produce an SSLSocket: <class>'.","triggerScenarios":"Using TlsServerCredentials with a custom SocketFactory (customSSLSocketFactory) whose createSocket(Socket, host, port, autoClose) returns a plain Socket during server handshake.","commonSituations":"Custom socket factories that ignore the autoClose/delegate contract, factories implemented for client-side use only, test stubs returning raw sockets.","solutions":["Make the custom factory's createSocket overloads return SSLSockets built from an SSLContext.getSocketFactory() wrapping the delegate socket","Prefer TlsServerCredentials.keyManager/trustManager so gRPC constructs TLS sockets itself","Confirm the factory passed to TlsServerCredentials.Builder is a factory intended for server-side TLS layering"],"exampleFix":"// before\nreturn new Socket(server, port);\n// after\nreturn tlsContext.getSocketFactory().createSocket(socket, host, port, autoClose);","handlingStrategy":"validation","validationCode":"Socket s = myFactory.createSocket();\nif (!(s instanceof SSLSocket)) throw new IllegalStateException(\"Custom socket factory must produce SSLSocket\");","typeGuard":null,"tryCatchPattern":"try { transport = handshake(socket, attrs); }\ncatch (IOException e) {\n  if (e.getMessage().contains(\"did not produce an SSLSocket\")) { /* replace or fix factory */ }\n}","preventionTips":["Test custom SocketFactory createSocket overloads before wiring into TlsServerCredentials","Use server-side TLS-aware factories only","Default to TlsServerCredentials.keyManager/trustManager instead of custom factories"],"tags":["grpc","java","tls","sslsocket","handshake"],"backgroundTag":"tls-handshake-failure","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"}