apache/druid · error · IllegalStateException
written out already
Error message
written out already
What it means
IntermediateColumnarLongsSerializer buffers longs into a temp output; once the column has been serialized (written out), the delegate is set and add() is permanently disabled. Calling add() after that transition throws this IllegalStateException because new values can no longer be inserted into the finished column.
Solutions
- Create a new IntermediateColumnarLongsSerializer for each column instead of reusing a finished one
- Ensure all add() calls happen before close()/serialization completes
- Audit aggregation code paths for values arriving after the column was flushed
Example fix
// before serializer.close(); serializer.add(42L); // throws // after serializer.close(); IntermediateColumnarLongsSerializer next = serializerFactory.makeSerializer(...); next.add(42L);
Defensive patterns
Strategy: validation
Validate before calling
if (serializer.isDone()) { serializer = factory.makeSerializer(...); } Try / catch
try { serializer.add(v); } catch (IllegalStateException e) { throw new IOException("column already finalized; create a new serializer", e); } Prevention
- Call add() strictly before close()/writeTo()
- Use one serializer per column; never reuse after finalization
- Track flush state in ingestion code paths
When it happens
Trigger: Calling add(long) after close()/writeTo() has completed serialization of the column; reusing a serializer across columns without constructing a new instance.
Common situations: Custom segment generation code that keeps appending after finishing a column; aggregation logic that writes more rows than declared to the ingester; reusing a serializer object for multiple input files.
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
- Incompatible serializer for type
- written out already
- Actual Row count mismatch. Expected
- Attempt to add row to swapped-out sink for segment
- Column capacity exceeded
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/b2bd76ebaf987630.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/data/IntermediateColumnarLongsSerializer.java:97
@Override
public void open()
{
tempOut = new LongArrayList();
}
@Override
public int size()
{
return numInserted;
}
@Override
public void add(long value)
{
//noinspection VariableNotUsedInsideIf
if (delegate != null) {
throw new IllegalStateException("written out already");
}
tempOut.add(value);
++numInserted;
if (numInserted < 0) {
throw new ColumnCapacityExceededException(columnName);
}
if (uniqueValues.size() <= CompressionFactory.MAX_TABLE_SIZE && !uniqueValues.containsKey(value)) {
uniqueValues.put(value, uniqueValues.size());
valuesAddedInOrder.add(value);
}
if (value > maxVal) {
maxVal = value;
}
if (value < minVal) {
minVal = value;
}
}
View on GitHub (pinned to 9b90983fd2)