{"record":{"id":"c3994cd5a9ed7d24","repo":"TooTallNate/Java-WebSocket","slug":"connection-is-closed","errorCode":null,"errorMessage":"Connection is closed","messagePattern":"Connection is closed","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/java_websocket/SSLSocketChannel2.java","lineNumber":285,"sourceCode":"    inCrypt.rewind();\n    inCrypt.flip();\n    outCrypt.rewind();\n    outCrypt.flip();\n    bufferallocations++;\n  }\n\n  public int write(ByteBuffer src) throws IOException {\n    if (!isHandShakeComplete()) {\n      processHandshake(false);\n      return 0;\n    }\n    // assert(bufferallocations > 1); // see #190\n    // if(bufferallocations <= 1) {\n    //   createBuffers(sslEngine.getSession());\n    // }\n    int num = socketChannel.write(wrap(src));\n    if (writeEngineResult.getStatus() == SSLEngineResult.Status.CLOSED) {\n      throw new EOFException(\"Connection is closed\");\n    }\n    return num;\n\n  }\n\n  /**\n   * Blocks when in blocking mode until at least one byte has been decoded.<br> When not in blocking\n   * mode 0 may be returned.\n   *\n   * @return the number of bytes read.\n   **/\n  public int read(ByteBuffer dst) throws IOException {\n    tryRestoreCryptedData();\n    while (true) {\n      if (!dst.hasRemaining()) {\n        return 0;\n      }\n      if (!isHandShakeComplete()) {","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/TooTallNate/Java-WebSocket/blob/afeacbf8c0f6f6a761c9d9daed8c813dd3b8ed7d/src/main/java/org/java_websocket/SSLSocketChannel2.java#L267-L303","documentation":"SSLSocketChannel2.write() throws EOFException when, after attempting to wrap and write data, the SSLEngine reports Status.CLOSED — i.e. the TLS session has already been closed (close_notify received or engine closed) and no more application data can be sent. The library converts this TLS state into EOFException so callers stop writing.","triggerScenarios":"Calling write()/send() on a WebSocket whose SSL engine has closed: after the peer sent close_notify, after closeConnection was initiated, or a concurrent write raced with the close handshake.","commonSituations":"Sending a message from another thread while the connection is closing; server closed the connection but the client queue still has pending frames; missed the onClose callback before issuing a send.","solutions":["Check websocket.isOpen() (or ReadyState == OPEN) before sending.","Route all sends through a single thread or synchronize access so writes cannot race with close.","Catch WebsocketNotConnectedException/EOFException around send() and drop or requeue the message.","Reconnect via WebSocketClient.reconnect() if the message must be delivered after an unexpected close."],"exampleFix":"// before\nconn.send(payload);\n// after\nif (conn.isOpen()) {\n  conn.send(payload);\n} else {\n  queueForResend(payload);\n}","handlingStrategy":"type-guard","validationCode":"if (!conn.isOpen()) { /* skip or queue send */ }","typeGuard":"boolean canSend = conn != null && conn.isOpen() && conn.getReadyState().equals(ReadyState.OPEN);","tryCatchPattern":"try { conn.send(data); } catch (WebsocketNotConnectedException | EOFException e) { queueForResend(data); }","preventionTips":["Always check isOpen() before send","Serialize all sends through one thread/executor","Don't hold references to sockets after onClose fires"],"tags":["tls","connection-closed","write","race-condition"],"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"}