{"record":{"id":"8544f32b5d869b9a","repo":"apache/druid","slug":"error-closing-org-apache-druid-query-aggregation-s-8544f3","errorCode":null,"errorMessage":"error closing org.apache.druid.query.aggregation.SerializablePairLongFloatComplexColumn","messagePattern":"error closing org\\.apache\\.druid\\.query\\.aggregation\\.SerializablePairLongFloatComplexColumn","errorType":"exception","errorClass":"ResponseException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/aggregation/SerializablePairLongFloatComplexColumn.java","lineNumber":86,"sourceCode":"  public Object getRowValue(int rowNum)\n  {\n    return serde.deserialize(cellReader.getCell(rowNum));\n  }\n\n  @Override\n  public int getLength()\n  {\n    return serializedSize;\n  }\n\n  @Override\n  public void close()\n  {\n    try {\n      closer.close();\n    }\n    catch (IOException e) {\n      throw new RE(e, \"error closing \" + getClass().getName());\n    }\n  }\n\n  public static class Builder\n  {\n    private final int serializedSize;\n    private final AbstractSerializablePairLongObjectDeltaEncodedStagedSerde<?> serde;\n    private final CellReader.Builder cellReaderBuilder;\n\n    public Builder(ByteBuffer buffer)\n    {\n      ByteBuffer masterByteBuffer = buffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder());\n\n      serializedSize = masterByteBuffer.remaining();\n\n      AbstractSerializablePairLongObjectColumnHeader<?> columnHeader =\n          AbstractSerializablePairLongObjectColumnHeader.fromBuffer(masterByteBuffer, SerializablePairLongFloat.class);\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/aggregation/SerializablePairLongFloatComplexColumn.java#L68-L104","documentation":"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.","triggerScenarios":"close() is invoked and the underlying Closeable (e.g., file channel or mapped byte buffer resource) throws IOException during close.","commonSituations":"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.","solutions":["Look at the IOException cause to identify which underlying resource failed to close and fix that I/O condition","Avoid closing the underlying channel independently of the Closer (prevents double-close failures)","Ensure segment lifecycle ownership is clear — only one component closes the column","Check filesystem health/permissions on the segment storage location"],"exampleFix":"// before\ncloser.close(); // IOException propagates as RE\n// after\ntry {\n  closer.close();\n} catch (IOException e) {\n  LOG.debug(e, \"ignoring close failure for %s\", getClass().getName());\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  column.close();\n} catch (RE e) {\n  if (e.getCause() instanceof IOException) {\n    LOG.warn(e, \"failed to close SerializablePairLongFloatComplexColumn\");\n  } else {\n    throw e;\n  }\n}","preventionTips":["Register all underlying Closeables once with the Closer and let it manage ordering","Avoid races between segment cleanup and column close (single lifecycle owner)","Check filesystem health and permissions on segment directories","Watch logs for repeated close failures pointing at leaked descriptors"],"tags":["java","io","resource-cleanup"],"backgroundTag":"file-close-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}