apache/cassandra · error · IllegalStateException
channel's transferring state is currently set to true. refus
Error message
channel's transferring state is currently set to true. refusing to start new stream
What it means
NettyStreamingChannel multiplexes stream transfers over one connection, using a TRANSFERRING_FILE_ATTR flag to guarantee only one outbound transfer at a time. acquireOut() uses compareAndSet(false, true); if the flag is already true, another transfer holds the channel, and it throws this IllegalStateException rather than interleaving transfers.
Source
Thrown at src/java/org/apache/cassandra/streaming/async/NettyStreamingChannel.java:131
{
return peer();
}
@Override
public boolean connected()
{
return channel.isOpen();
}
public StreamingDataInputPlus in()
{
return in;
}
public StreamingDataOutputPlus acquireOut()
{
if (!channel.attr(TRANSFERRING_FILE_ATTR).compareAndSet(false, true))
throw new IllegalStateException("channel's transferring state is currently set to true. refusing to start new stream");
return new AsyncStreamingOutputPlus(channel)
{
@Override
public void close() throws IOException
{
try
{
super.close();
}
finally
{
NettyStreamingChannel.this.channel.attr(TRANSFERRING_FILE_ATTR).set(FALSE);
}
}
};
}
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Ensure acquireOut() results are always closed (try-with-resources) so TRANSFERRING_FILE_ATTR resets; look for leaked transfers on the channel.
- Reduce streaming concurrency (stream_throughput_outbound, concurrent stream sessions) so fewer transfers contend per channel.
- Check for stuck prior transfers (long-running FileStreamTask) to the peer and cancel/retry the session.
- Upgrade to a version where channel acquisition is queued rather than failing hard, or retry the stream session after the current transfer completes.
Example fix
// before
StreamingDataOutputPlus out = channel.acquireOut();
out.write(...);
// flag may stay set on exception
// after
try (StreamingDataOutputPlus out = channel.acquireOut()) {
out.write(...);
} // close() resets TRANSFERRING_FILE_ATTR Defensive patterns
Strategy: try-catch
Validate before calling
if (channel.attr(TRANSFERRING_FILE_ATTR).get()) { /* wait or pick another channel */ } Try / catch
try (StreamingDataOutputPlus out = channel.acquireOut()) { out.write(...); } catch (IllegalStateException e) { if (e.getMessage().contains("transferring state")) { retryAfterCurrentTransfer(); } else { throw e; } } Prevention
- Always use try-with-resources for acquireOut() results so the flag resets on failure.
- Limit concurrent streaming sessions/throughput per peer.
- Monitor for stuck transfers that never release the channel.
When it happens
Trigger: Calling acquireOut() on a NettyStreamingChannel that already has an active transfer — e.g. submitting a second FileStreamTask on the same channel while a file is still being transferred, or a leak where a previous transfer never released the flag (close not called).
Common situations: High streaming concurrency saturating the per-session channel pool; an earlier transfer aborted by exception without closing the AsyncStreamingOutputPlus (flag never reset); simultaneous repairs/streams hitting the same peer.
Related errors
- Node is still rebuilding. Check nodetool netstats.
- Transfer of stream %s already completed or aborted (perhaps
- Queue is empty
- UnsupportedOperationException
- Maximum pool size has been changed while resizing
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/56081a0eddbb7d9c.
Report an issue: GitHub.