{"record":{"id":"26f5e24c460f2f23","repo":"apache/iceberg","slug":"failed-to-close-position-delete-source","errorCode":null,"errorMessage":"Failed to close position delete source","messagePattern":"Failed to close position delete source","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/deletes/Deletes.java","lineNumber":162,"sourceCode":"   */\n  public static <T extends StructLike> CharSequenceMap<PositionDeleteIndex> toPositionIndexes(\n      CloseableIterable<T> posDeletes, DeleteFile file) {\n    CharSequenceMap<PositionDeleteIndex> indexes = CharSequenceMap.create();\n\n    try (CloseableIterable<T> deletes = posDeletes) {\n      String lastFilePath = null;\n      PositionDeleteIndex index = null;\n      for (T delete : deletes) {\n        CharSequence filePath = (CharSequence) FILENAME_ACCESSOR.get(delete);\n        long position = (long) POSITION_ACCESSOR.get(delete);\n        if (lastFilePath == null || !lastFilePath.contentEquals(filePath)) {\n          lastFilePath = filePath.toString();\n          index = indexes.computeIfAbsent(filePath, key -> new BitmapPositionDeleteIndex(file));\n        }\n        index.delete(position);\n      }\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to close position delete source\", e);\n    }\n\n    return indexes;\n  }\n\n  public static <T extends StructLike> PositionDeleteIndex toPositionIndex(\n      CharSequence dataLocation, CloseableIterable<T> posDeletes, DeleteFile file) {\n    CloseableIterable<Long> positions = extractPositions(dataLocation, posDeletes);\n    List<DeleteFile> files = ImmutableList.of(file);\n    return toPositionIndex(positions, files);\n  }\n\n  private static <T extends StructLike> CloseableIterable<Long> extractPositions(\n      CharSequence dataLocation, CloseableIterable<T> rows) {\n    DataFileFilter<T> filter = new DataFileFilter<>(dataLocation);\n    CloseableIterable<T> filteredRows = filter.filter(rows);\n    return CloseableIterable.transform(filteredRows, row -> (Long) POSITION_ACCESSOR.get(row));\n  }","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/deletes/Deletes.java#L144-L180","documentation":"Deletes.toPositionIndexes consumes a CloseableIterable of position deletes, grouping positions into BitmapPositionDeleteIndex per data file, and closes the iterable at the end of a try block. If close() throws an IOException the library wraps it in UncheckedIOException. The indexes are built but the underlying delete-file streams failed to close cleanly.","triggerScenarios":"Calling Deletes.toPositionIndexes(CloseableIterable<PositionDelete>, ...) where the delete-file reader's close() raises IOException - e.g. Avro reader over a delete file that failed to flush/truncate or whose storage endpoint is unreachable at close time.","commonSituations":"S3/HDFS transient failures when finishing delete-file reads; delete files removed concurrently by expiration; misconfigured FileIO credentials surfacing only at stream finalization.","solutions":["Read the wrapped cause to identify the storage-level failure and fix FileIO config/permissions","Ensure delete files are not being expired or rewritten concurrently while being read","Retry the operation; transient object-storage errors often resolve","Check network/filesystem stability between compute and storage layers"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-verify delete files are readable and not being expired\nif (table.io().newInputFile(deleteFile.location()).exists()) { ... }","typeGuard":null,"tryCatchPattern":"try {\n  CharSequenceMap<PositionDeleteIndex> idx = Deletes.toPositionIndexes(posDeletes);\n} catch (UncheckedIOException e) {\n  throw new RetryableException(\"Delete source close failed: \" + e.getCause().getMessage(), e.getCause());\n}","preventionTips":["Avoid concurrent file expiration during reads (snapshot expiration locking/min age)","Configure storage client retries for transient S3/HDFS errors","Close plan/scan resources promptly to reduce window for external interference","Monitor storage health; alert on elevated close-time IO failures"],"tags":["io","unchecked-ioexception","position-delete","resource-cleanup"],"backgroundTag":"file-read-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}