{"record":{"id":"ec2f3f7af7e85359","repo":"apache/cassandra","slug":"the-channel-this-output-stream-was-writing-to-has","errorCode":null,"errorMessage":"The channel this output stream was writing to has been closed","messagePattern":"The channel this output stream was writing to has been closed","errorType":"exception","errorClass":"FlushException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/net/AsyncChannelOutputPlus.java","lineNumber":201,"sourceCode":"     * This may only be invoked by the eventLoop, never by the writer thread.\n     */\n    protected void releaseSpace(long bytesFlushed)\n    {\n        long newFlushed = flushed + bytesFlushed;\n        flushed = newFlushed;\n\n        Thread thread = waiting;\n        if (thread != null && signalWhenFlushed <= newFlushed)\n            LockSupport.unpark(thread);\n    }\n\n    private void propagateFailedFlush() throws IOException\n    {\n        Throwable t = flushFailed;\n        if (t != null)\n        {\n            if (SocketFactory.isCausedByConnectionReset(t))\n                throw new FlushException(\"The channel this output stream was writing to has been closed\", t);\n            throw new FlushException(\"This output stream is in an unsafe state after an asynchronous flush failed\", t);\n        }\n    }\n\n    @Override\n    abstract protected void doFlush(int count) throws IOException;\n\n    abstract public long position();\n\n    public long flushed()\n    {\n        // external flushed (that which has had flush() invoked implicitly or otherwise) == internal flushing\n        return flushing;\n    }\n\n    public long flushedToNetwork()\n    {\n        return flushedToNetwork;","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/net/AsyncChannelOutputPlus.java#L183-L219","documentation":"AsyncChannelOutputPlus waits for asynchronous channel flushes to complete; propagateFailedFlush converts a stored flush failure into a FlushException. When the underlying failure is a connection reset (SocketFactory.isCausedByConnectionReset), the message indicates the channel the stream was writing to has been closed — i.e. the remote peer is gone.","triggerScenarios":"A flush issued asynchronously to the socket channel fails because the connection was reset by the peer (TCP RST) or the channel was closed; waitUntilFlushed then surfaces this via propagateFailedFlush.","commonSituations":"Remote node crashed or restarted mid-stream; network interruption/severed TCP connection during streaming; peer closed the socket while this node was still writing data.","solutions":["Retry the streaming operation once the peer is back and the connection is re-established","Inspect logs on the remote node to determine why it closed/reset the connection","Check network stability (firewalls, load balancer idle timeouts) between nodes","Ensure the application handles FlushException by aborting the in-flight stream cleanly"],"exampleFix":"// before\noutput.writeFileToChannel(...); // throws FlushException on reset\n\n// after\ntry {\n    output.writeFileToChannel(...);\n} catch (FlushException e) {\n    logger.warn(\"Peer connection lost during stream, scheduling retry\", e);\n    scheduleStreamRetry(plan);\n}\n","handlingStrategy":"try-catch","validationCode":"// proactively check channel state\nif (!channel.isOpen()) throw new IOException(\"Channel already closed before streaming\");","typeGuard":null,"tryCatchPattern":"try { output.writeFileToChannel(file, length, limits); }\ncatch (FlushException e) {\n  if (e.getMessage().contains(\"closed\")) { scheduleStreamRetry(plan); }\n  else throw e;\n}","preventionTips":["Monitor peer health before starting long streams","Handle node restarts/crashes as expected streaming failures","Set appropriate TCP keepalive and firewall idle timeouts"],"tags":["network","streaming","connection-reset"],"backgroundTag":"broken-pipe","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}