apache/iceberg · error · UncheckedIOException
Failed to close position delete source
Error message
Failed to close position delete source
What it means
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.
Source
Thrown at core/src/main/java/org/apache/iceberg/deletes/Deletes.java:162
*/
public static <T extends StructLike> CharSequenceMap<PositionDeleteIndex> toPositionIndexes(
CloseableIterable<T> posDeletes, DeleteFile file) {
CharSequenceMap<PositionDeleteIndex> indexes = CharSequenceMap.create();
try (CloseableIterable<T> deletes = posDeletes) {
String lastFilePath = null;
PositionDeleteIndex index = null;
for (T delete : deletes) {
CharSequence filePath = (CharSequence) FILENAME_ACCESSOR.get(delete);
long position = (long) POSITION_ACCESSOR.get(delete);
if (lastFilePath == null || !lastFilePath.contentEquals(filePath)) {
lastFilePath = filePath.toString();
index = indexes.computeIfAbsent(filePath, key -> new BitmapPositionDeleteIndex(file));
}
index.delete(position);
}
} catch (IOException e) {
throw new UncheckedIOException("Failed to close position delete source", e);
}
return indexes;
}
public static <T extends StructLike> PositionDeleteIndex toPositionIndex(
CharSequence dataLocation, CloseableIterable<T> posDeletes, DeleteFile file) {
CloseableIterable<Long> positions = extractPositions(dataLocation, posDeletes);
List<DeleteFile> files = ImmutableList.of(file);
return toPositionIndex(positions, files);
}
private static <T extends StructLike> CloseableIterable<Long> extractPositions(
CharSequence dataLocation, CloseableIterable<T> rows) {
DataFileFilter<T> filter = new DataFileFilter<>(dataLocation);
CloseableIterable<T> filteredRows = filter.filter(rows);
return CloseableIterable.transform(filteredRows, row -> (Long) POSITION_ACCESSOR.get(row));
}View on GitHub (pinned to 86d9c8fc54)
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
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-verify delete files are readable and not being expired
if (table.io().newInputFile(deleteFile.location()).exists()) { ... } Try / catch
try {
CharSequenceMap<PositionDeleteIndex> idx = Deletes.toPositionIndexes(posDeletes);
} catch (UncheckedIOException e) {
throw new RetryableException("Delete source close failed: " + e.getCause().getMessage(), e.getCause());
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: S3/HDFS transient failures when finishing delete-file reads; delete files removed concurrently by expiration; misconfigured FileIO credentials surfacing only at stream finalization.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Failed to close encryption manager
- Failed to close equality delete source
- Failed to close current writer
- Failed to close iterable
- Failed to close current writer
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/26f5e24c460f2f23.
Report an issue: GitHub.