apache/druid · error · IllegalStateException
Writable channel is not available. The output channel might
Error message
Writable channel is not available. The output channel might be marked as read-only, hence no writes are allowed.
What it means
PartitionedOutputChannel wraps a per-partition OutputChannel; when created read-only the writable channel is never assigned (null). getWritableChannel() then throws ISE, because a producer is attempting to write to a channel that is explicitly marked read-only. Callers listed (openPartitionedChannel, runMerger, writableFrameChannel) are internal paths that only fetch it when writing is expected.
Source
Thrown at processing/src/main/java/org/apache/druid/frame/processor/PartitionedOutputChannel.java:91
final MemoryAllocator frameMemoryAllocator,
final Supplier<PartitionedReadableFrameChannel> readableChannelSupplier
)
{
return new PartitionedOutputChannel(
Preconditions.checkNotNull(writableChannel, "writableChannel"),
Preconditions.checkNotNull(frameMemoryAllocator, "frameMemoryAllocator"),
readableChannelSupplier
);
}
/**
* Returns the writable channel of this pair. The producer writes to this channel. Throws ISE if the output channel is
* read only.
*/
public synchronized WritableFrameChannel getWritableChannel()
{
if (writableChannel == null) {
throw new ISE("Writable channel is not available. The output channel might be marked as read-only,"
+ " hence no writes are allowed.");
} else {
return writableChannel;
}
}
/**
* Returns the memory allocator for the writable channel. The producer uses this to generate frames for the channel.
* Throws ISE if the output channel is read only.
*/
public synchronized MemoryAllocator getFrameMemoryAllocator()
{
if (frameMemoryAllocator == null) {
throw new ISE("Frame allocator is not available. The output channel might be marked as read-only,"
+ " hence memory allocator is not required.");
} else {
return frameMemoryAllocator;
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Create the output channel with readOnly=false if producers must write to it.
- Check writableFrameChannel()/readOnly state before writing and route writes to the correct non-read-only channel.
- Ensure each partition's producer is wired to its own writable OutputChannel rather than a shared read-only one.
Example fix
// before PartitionedOutputChannel out = new PartitionedOutputChannel(channels, readOnly); out.getWritableChannel().write(frame); // after PartitionedOutputChannel out = new PartitionedOutputChannel(channels, false); out.getWritableChannel().write(frame);
Defensive patterns
Strategy: try-catch
Validate before calling
if (outputChannel.isReadOnly()) {
throw new IllegalStateException("Refusing to write to read-only output channel");
} Type guard
boolean writable(PartitionedOutputChannel ch) { return !ch.isReadOnly(); } Try / catch
try {
WritableFrameChannel w = outputChannel.getWritableChannel();
} catch (IllegalStateException e) {
// route writes to a writable channel or re-create with readOnly=false
} Prevention
- Keep producer and consumer channel wiring separate.
- Audit readOnly flags when refactoring stage code.
- Fetch the writable channel once at producer setup.
When it happens
Trigger: Constructing PartitionedOutputChannel with readOnly=true and later calling getWritableChannel(); sharing a read-only output channel across stages where one stage still tries to write frames to it.
Common situations: Query-stage wiring where an output is marked read-only (e.g. broadcast/read-only consumers) but a producer incorrectly targets it; tests reusing a read-only channel for writes; refactors that changed the readOnly flag without updating writers.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- No such stage[%s]
- Frame allocator is not available. The output channel might b
- Cannot have both awaitChannels and awaitFutures
- Expected single element
- Can't add [%d, %s] to non-empty SingleEntryShort2ObjectSorte
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/f485592758e906ce.
Report an issue: GitHub.