{"record":{"id":"0483474f59d0fdc9","repo":"TooTallNate/Java-WebSocket","slug":"connection-closed-unexpectedly-by-peer","errorCode":null,"errorMessage":"connection closed unexpectedly by peer","messagePattern":"connection closed unexpectedly by peer","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/java_websocket/SSLSocketChannel2.java","lineNumber":175,"sourceCode":"      while (it.hasNext()) {\n        Future<?> f = it.next();\n        if (f.isDone()) {\n          it.remove();\n        } else {\n          if (isBlocking()) {\n            consumeFutureUninterruptible(f);\n          }\n          return;\n        }\n      }\n    }\n\n    if (isReading && sslEngine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {\n      if (!isBlocking() || readEngineResult.getStatus() == Status.BUFFER_UNDERFLOW) {\n        inCrypt.compact();\n        int read = socketChannel.read(inCrypt);\n        if (read == -1) {\n          throw new IOException(\"connection closed unexpectedly by peer\");\n        }\n        inCrypt.flip();\n      }\n      inData.compact();\n      unwrap();\n      if (readEngineResult.getHandshakeStatus() == HandshakeStatus.FINISHED) {\n        createBuffers(sslEngine.getSession());\n        return;\n      }\n    }\n    consumeDelegatedTasks();\n    if (tasks.isEmpty()\n        || sslEngine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP) {\n      socketChannel.write(wrap(emptybuffer));\n      if (writeEngineResult.getHandshakeStatus() == HandshakeStatus.FINISHED) {\n        createBuffers(sslEngine.getSession());\n        return;\n      }","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/TooTallNate/Java-WebSocket/blob/afeacbf8c0f6f6a761c9d9daed8c813dd3b8ed7d/src/main/java/org/java_websocket/SSLSocketChannel2.java#L157-L193","documentation":"SSLSocketChannel2.read() throws this IOException during the TLS handshake (NEED_UNWRAP phase) when socketChannel.read() returns -1, meaning the underlying TCP connection was closed by the remote peer while encrypted handshake bytes were still expected. The library surfaces this instead of silently treating it as a normal close because the SSL handshake never completed, so the WebSocket connection state is ambiguous.","triggerScenarios":"The remote peer (or an intermediary like a proxy/load balancer) closes the TCP socket after the TLS ClientHello/ServerHello exchange begins but before the handshake finishes — e.g. server rejects the TLS version/cipher, a timeout fires mid-handshake, or the peer crashes.","commonSituations":"Connecting through a corporate proxy or firewall that drops TLS connections; server only supports TLS versions the client does not offer; port forwarded to a non-TLS service; aggressive idle timeouts on load balancers; server closing connections during TLS renegotiation.","solutions":["Check server TLS configuration (supported protocols/ciphers) and ensure the client's enabled protocols overlap (e.g. set system property https.protocols or SSLSocketFactory accordingly).","Verify network path: if behind a proxy/firewall, confirm it allows the CONNECT/TLS traffic and does not time out mid-handshake.","Confirm the target port actually serves TLS (wss://) and not plain ws://.","Retry with reconnect/backoff and inspect server-side logs at the exact time of the failure to see why the peer closed.","Update to a recent TooTallNate/Java-WebSocket version where handshake failures surface clearer error messages."],"exampleFix":"// before: immediate connect without TLS config\nWebSocketClient client = new WebSocketClient(uri);\n// after: pin compatible TLS protocols before connecting\nSSLContext ctx = SSLContext.getInstance(\"TLSv1.2\");\nctx.init(null, trustAllCerts, new SecureRandom());\nclient.setSocketFactory(ctx.getSocketFactory());","handlingStrategy":"retry","validationCode":"// verify URI scheme and TLS support before connecting\nif (!uri.getScheme().equals(\"wss\")) throw new IllegalArgumentException(\"use wss://\");\nSSLContext ctx = SSLContext.getInstance(\"TLSv1.2\");\nctx.init(null, trustedCerts, new SecureRandom());\nclient.setSocketFactory(ctx.getSocketFactory());","typeGuard":null,"tryCatchPattern":"try { client.connectBlocking(); } catch (IOException e) {\n  if (e.getMessage().contains(\"connection closed unexpectedly\")) { scheduleReconnectWithBackoff(); }\n}","preventionTips":["Align enabled TLS protocols/ciphers between client and server","Confirm proxies/firewalls allow the TLS traffic and don't time out mid-handshake","Use wss:// only against endpoints that actually serve TLS","Add reconnect-with-backoff for transient network drops"],"tags":["tls","network","handshake","connection-closed"],"backgroundTag":"connection-closed-by-peer","analyzedSha":"afeacbf8c0f6f6a761c9d9daed8c813dd3b8ed7d","analyzedAt":"2026-09-09T14:39:47.546Z","contentChangedAt":"2026-09-09T14:39:47.546Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}