apache/cassandra · error · FlushException
The channel this output stream was writing to has been close
Error message
The channel this output stream was writing to has been closed
What it means
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.
Source
Thrown at src/java/org/apache/cassandra/net/AsyncChannelOutputPlus.java:201
* This may only be invoked by the eventLoop, never by the writer thread.
*/
protected void releaseSpace(long bytesFlushed)
{
long newFlushed = flushed + bytesFlushed;
flushed = newFlushed;
Thread thread = waiting;
if (thread != null && signalWhenFlushed <= newFlushed)
LockSupport.unpark(thread);
}
private void propagateFailedFlush() throws IOException
{
Throwable t = flushFailed;
if (t != null)
{
if (SocketFactory.isCausedByConnectionReset(t))
throw new FlushException("The channel this output stream was writing to has been closed", t);
throw new FlushException("This output stream is in an unsafe state after an asynchronous flush failed", t);
}
}
@Override
abstract protected void doFlush(int count) throws IOException;
abstract public long position();
public long flushed()
{
// external flushed (that which has had flush() invoked implicitly or otherwise) == internal flushing
return flushing;
}
public long flushedToNetwork()
{
return flushedToNetwork;View on GitHub (pinned to 88fd0f6a0e)
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
Example fix
// before
output.writeFileToChannel(...); // throws FlushException on reset
// after
try {
output.writeFileToChannel(...);
} catch (FlushException e) {
logger.warn("Peer connection lost during stream, scheduling retry", e);
scheduleStreamRetry(plan);
}
Defensive patterns
Strategy: try-catch
Validate before calling
// proactively check channel state
if (!channel.isOpen()) throw new IOException("Channel already closed before streaming"); Try / catch
try { output.writeFileToChannel(file, length, limits); }
catch (FlushException e) {
if (e.getMessage().contains("closed")) { scheduleStreamRetry(plan); }
else throw e;
} Prevention
- Monitor peer health before starting long streams
- Handle node restarts/crashes as expected streaming failures
- Set appropriate TCP keepalive and firewall idle timeouts
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- This output stream is in an unsafe state after an asynchrono
- failed to connect to %s for streaming data
- Can not start range streaming as all candidates (%s) are dow
- Streaming to the following hosts failed:
- [Stream {}] Error while reading partition {} from stream on
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ec2f3f7af7e85359.
Report an issue: GitHub.