apache/iceberg · error · UncheckedIOException
Failed to close iterable
Error message
Failed to close iterable
What it means
BaseDeleteLoader.materialize eagerly copies a CloseableIterable into an in-memory list so the loaded delete entries can be cached. When closing the underlying iterable's resources (file handles/readers) fails with an IOException, it is rethrown as an UncheckedIOException with this message. The delete entries were likely already read; only resource cleanup failed.
Source
Thrown at data/src/main/java/org/apache/iceberg/data/BaseDeleteLoader.java:136
private Iterable<StructLike> readEqDeletes(DeleteFile deleteFile, Schema projection) {
CloseableIterable<Record> deletes = openDeletes(deleteFile, projection);
CloseableIterable<Record> copiedDeletes = CloseableIterable.transform(deletes, Record::copy);
CloseableIterable<StructLike> copiedDeletesAsStructs = toStructs(copiedDeletes, projection);
return materialize(copiedDeletesAsStructs);
}
private CloseableIterable<StructLike> toStructs(
CloseableIterable<Record> records, Schema schema) {
InternalRecordWrapper wrapper = new InternalRecordWrapper(schema.asStruct());
return CloseableIterable.transform(records, wrapper::copyFor);
}
// materializes the iterable and releases resources so that the result can be cached
private <T> Iterable<T> materialize(CloseableIterable<T> iterable) {
try (CloseableIterable<T> closeableIterable = iterable) {
return ImmutableList.copyOf(closeableIterable);
} catch (IOException e) {
throw new UncheckedIOException("Failed to close iterable", e);
}
}
/**
* Loads the content of a deletion vector or position delete files for a given data file path into
* a position index.
*
* <p>The deletion vector is currently loaded without caching as the existing Puffin reader
* requires at least 3 requests to fetch the entire file. Caching a single deletion vector may
* only be useful when multiple data file splits are processed on the same node, which is unlikely
* as task locality is not guaranteed.
*
* <p>For position delete files, however, there is no efficient way to read deletes for a
* particular data file. Therefore, caching may be more effective as such delete files potentially
* apply to many data files, especially in unpartitioned tables and tables with deep partitions.
* If a position delete file qualifies for caching, this method will attempt to cache a position
* index for each referenced data file.
*View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check the chained cause (getCause()) for the real storage/IO error and fix storage connectivity/permissions.
- Retry the delete-file load; transient network failures on close are often recoverable.
- Verify the FileIO configuration (timeouts, credentials, endpoint) matches the storage system.
- If it persists, check for a FileIO implementation bug and report with the cause stack.
Example fix
// before: unhandled transient close failure kills the read
Iterable<Record> deletes = loader.readEqDeletes(deleteFiles);
// after: retry transient IO failures
try {
Iterable<Record> deletes = loader.readEqDeletes(deleteFiles);
} catch (UncheckedIOException e) {
// inspect e.getCause(); retry with backoff or fail the task with the cause
throw new RuntimeException("Retry delete load", e.getCause());
} Defensive patterns
Strategy: try-catch
Try / catch
try {
Iterable<T> deletes = loader.readEqDeletes(deleteFiles);
} catch (UncheckedIOException e) {
Throwable cause = e.getCause();
if (isTransient(cause)) { retryWithBackoff(); } else { throw e; }
} Prevention
- Use reliable FileIO implementations with sane timeouts and retries configured.
- Monitor storage health; close failures usually mirror connectivity problems seen elsewhere.
- Keep Iceberg versions current — close-path bugs are fixed over time.
When it happens
Trigger: Calling readEqDeletes/readPosDeletes (e.g. via DeleteFilter.applyEqDeletes/applyPosDeletes) when the deletion vector or position delete file's closeable iterator cannot release its underlying input stream — typically an I/O error on the underlying FileIO during close.
Common situations: Underlying storage (HDFS/S3/local FS) errors or timeouts while closing a delete-file reader; FileIO implementations that validate checksums or flush on close; network interruptions during scan of delete files.
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 position delete source
- Failed to close
- Failed to write delete manifests
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c77eff24c33db1e0.
Report an issue: GitHub.