apache/druid · error · ResponseException

error closing org.apache.druid.query.aggregation.Serializabl

Error message

error closing org.apache.druid.query.aggregation.SerializablePairLongFloatComplexColumn

What it means

SerializablePairLongFloatComplexColumn.close() delegates cleanup to a Closer and wraps any IOException thrown during close in a Druid RE with 'error closing <class name>'. It guards against silent resource leaks when a serialized pair-long-float column cannot be cleanly released.

Source

Thrown at processing/src/main/java/org/apache/druid/query/aggregation/SerializablePairLongFloatComplexColumn.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, SerializablePairLongFloat.class);

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Look at the IOException cause to identify which underlying resource failed to close and fix that I/O condition
  2. Avoid closing the underlying channel independently of the Closer (prevents double-close failures)
  3. Ensure segment lifecycle ownership is clear — only one component closes the column
  4. Check filesystem health/permissions on the segment storage location

Example fix

// before
closer.close(); // IOException propagates as RE
// after
try {
  closer.close();
} catch (IOException e) {
  LOG.debug(e, "ignoring close failure for %s", getClass().getName());
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  column.close();
} catch (RE e) {
  if (e.getCause() instanceof IOException) {
    LOG.warn(e, "failed to close SerializablePairLongFloatComplexColumn");
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: close() is invoked and the underlying Closeable (e.g., file channel or mapped byte buffer resource) throws IOException during close.

Common situations: Segment files removed or already closed by another component before column cleanup; filesystem/permission errors; double-close of channels registered in the Closer; broker/historical task shutdown ordering causing races on segment files.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/8544f32b5d869b9a. Report an issue: GitHub.