apache/iceberg · error · UncheckedIOException
Failed to close scan: ${scan}
Error message
Failed to close scan: ${scan} What it means
SparkPartitioningAwareScan.tasks() plans tasks and closes the scan with CloseableIterable; if closing the planned scan throws IOException, it is wrapped in UncheckedIOException with the scan's description. This signals leaked/planning resources (file handles, manifest readers) could not be released after task planning.
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkPartitioningAwareScan.java:197
protected synchronized List<T> tasks() {
if (tasks == null) {
try (CloseableIterable<? extends ScanTask> taskIterable = scan.planFiles()) {
List<T> plannedTasks = Lists.newArrayList();
for (ScanTask task : taskIterable) {
ValidationException.check(
taskJavaClass().isInstance(task),
"Unsupported task type, expected a subtype of %s: %s",
taskJavaClass().getName(),
task.getClass().getName());
plannedTasks.add(taskJavaClass().cast(task));
}
this.tasks = plannedTasks;
} catch (IOException e) {
throw new UncheckedIOException("Failed to close scan: " + scan, e);
}
}
return tasks;
}
@Override
protected synchronized List<ScanTaskGroup<T>> taskGroups() {
if (taskGroups == null) {
if (groupingKeyType().fields().isEmpty()) {
CloseableIterable<ScanTaskGroup<T>> plannedTaskGroups =
TableScanUtil.planTaskGroups(
CloseableIterable.withNoopClose(tasks()),
adjustSplitSize(tasks(), scan.targetSplitSize()),
scan.splitLookback(),
scan.splitOpenFileCost());
this.taskGroups = Lists.newArrayList(plannedTaskGroups);
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check the chained IOException cause for the underlying FileIO/close error and address it (network, permissions, custom FileIO bug)
- Raise the process file-descriptor limit (ulimit) if fd exhaustion is reported
- Use a well-tested FileIO implementation (HadoopFileIO / S3FileIO) instead of custom ones and retry the scan
Defensive patterns
Strategy: retry
Try / catch
try {
tasks = scan.tasks();
} catch (UncheckedIOException e) {
LOG.warn("Scan close failed, retrying", e.getCause());
tasks = scan.tasks();
} Prevention
- Raise ulimit -n if fd exhaustion is common
- Prefer maintained FileIO implementations over custom ones
- Retry scan planning on transient storage errors
When it happens
Trigger: task planning completes but closing the CloseableIterable of tasks throws IOException — typically an underlying FileIO error while closing manifest readers or input streams during plan() cleanup.
Common situations: Filesystem or object-store connectivity errors during close (S3 timeouts, HDFS client errors); exhausted file descriptors causing close failures; buggy custom FileIO implementations that throw on close().
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 scan: + scan
- Failed to close changelog scan: ${scan}
- Failed to close scan: ${scan}
- Failed to close changelog scan: + scan
- Failed to close task iterable
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/a0b7a1ccf7aad26a.
Report an issue: GitHub.