apache/druid · error · ResponseException
error closing org.apache.druid.query.aggregation.Serializabl
Error message
error closing org.apache.druid.query.aggregation.SerializablePairLongDoubleComplexColumn
What it means
SerializablePairLongDoubleComplexColumn.close() releases resources via a Closer. If closer.close() throws an IOException (e.g., while closing an underlying channel or file), it is wrapped in a Druid RE with the message 'error closing <class name>'. This signals a resource leak or I/O problem during cleanup of a serialized pair-long-double complex column.
Source
Thrown at processing/src/main/java/org/apache/druid/query/aggregation/SerializablePairLongDoubleComplexColumn.java:86
public Object getRowValue(int rowNum)
{
return serde.deserialize(cellReader.getCell(rowNum));
}
@Override
public int getLength()
{
return serializedSize;
}
@Override
public void close()
{
try {
closer.close();
}
catch (IOException e) {
throw new RE(e, "error closing " + getClass().getName());
}
}
public static class Builder
{
private final int serializedSize;
private final AbstractSerializablePairLongObjectDeltaEncodedStagedSerde<?> serde;
private final CellReader.Builder cellReaderBuilder;
public Builder(ByteBuffer buffer)
{
ByteBuffer masterByteBuffer = buffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder());
serializedSize = masterByteBuffer.remaining();
AbstractSerializablePairLongObjectColumnHeader<?> columnHeader =
AbstractSerializablePairLongObjectColumnHeader.fromBuffer(masterByteBuffer, SerializablePairLongDouble.class);
View on GitHub (pinned to 9b90983fd2)
Solutions
- Check that the underlying file/channel is not closed or deleted elsewhere before this column's close() runs
- Inspect the wrapped IOException (getCause()) for the real close failure and fix the underlying I/O issue
- Ensure the column is closed exactly once via the Closer/Try-style lifecycle (avoid manual close on top of a registered closer)
- Verify disk/filesystem health and permissions for the segment directory
Example fix
// before
closer.close(); // IOException propagates as RE
// after
try {
closer.close();
} catch (IOException e) {
LOG.warn(e, "error closing %s", getClass().getName()); // tolerate close failures during cleanup
} Defensive patterns
Strategy: try-catch
Try / catch
try {
column.close();
} catch (RE e) {
if (e.getCause() instanceof IOException) {
LOG.warn(e, "failed to close SerializablePairLongDoubleComplexColumn; possible leaked resource");
} else {
throw e;
}
} Prevention
- Let the Closer own the underlying resources — never close the channel/file manually as well
- Close columns before deleting or unmapping their backing segment files
- Monitor for IOException causes indicating already-closed channels (double-close) or missing files
- Run query cleanup on stable local storage; avoid force-terminating tasks mid-cleanup
When it happens
Trigger: Calling close() when the underlying Closeable held by the Closer fails to close — e.g., an IOException from closing the memory-mapped file or channel backing the serialized column.
Common situations: Underlying segment files already closed or deleted before the column; filesystem issues (NFS staleness, permission changes); double-close bugs where the channel was closed elsewhere and close() surfaces a retry failure; shutdown ordering issues in query/segment cleanup.
Related errors
- error closing org.apache.druid.query.aggregation.Serializabl
- error closing org.apache.druid.query.aggregation.Serializabl
- error closing org.apache.druid.query.aggregation.Serializabl
- Could not close channel for level [%d] and rank [%d]
- failed to close one or more emitters
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/2e3a47f2ee771e54.
Report an issue: GitHub.