{"record":{"id":"b927cdde29e04143","repo":"apache/iceberg","slug":"failed-to-close-scan-scan-b927cd","errorCode":null,"errorMessage":"Failed to close scan: \" + scan","messagePattern":"Failed to close scan: \" \\+ scan","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/SparkPartitioningAwareScan.java","lineNumber":197,"sourceCode":"\n  protected synchronized List<T> tasks() {\n    if (tasks == null) {\n      try (CloseableIterable<? extends ScanTask> taskIterable = scan.planFiles()) {\n        List<T> plannedTasks = Lists.newArrayList();\n\n        for (ScanTask task : taskIterable) {\n          ValidationException.check(\n              taskJavaClass().isInstance(task),\n              \"Unsupported task type, expected a subtype of %s: %s\",\n              taskJavaClass().getName(),\n              task.getClass().getName());\n\n          plannedTasks.add(taskJavaClass().cast(task));\n        }\n\n        this.tasks = plannedTasks;\n      } catch (IOException e) {\n        throw new UncheckedIOException(\"Failed to close scan: \" + scan, e);\n      }\n    }\n\n    return tasks;\n  }\n\n  @Override\n  protected synchronized List<ScanTaskGroup<T>> taskGroups() {\n    if (taskGroups == null) {\n      if (groupingKeyType().fields().isEmpty()) {\n        CloseableIterable<ScanTaskGroup<T>> plannedTaskGroups =\n            TableScanUtil.planTaskGroups(\n                CloseableIterable.withNoopClose(tasks()),\n                adjustSplitSize(tasks(), scan.targetSplitSize()),\n                scan.splitLookback(),\n                scan.splitOpenFileCost());\n        this.taskGroups = Lists.newArrayList(plannedTaskGroups);\n","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/SparkPartitioningAwareScan.java#L179-L215","documentation":"SparkPartitioningAwareScan.tasks converts IOException from closing/reading scan.planTasks() into UncheckedIOException, indicating batch scan planning failed while the task iterable was consumed or closed.","triggerScenarios":"IOException from the underlying FileIO during batch scan planning (manifest reads, object store errors) surfaced when Spark plans the batch read.","commonSituations":"Object-store outages or throttling during query planning; expired credentials; corrupted manifest/metadata files; HDFS unavailability.","solutions":["Read the caused-by chain for the root IOException","Retry the query; add retry/throttling config on the storage client","Verify FileIO credentials and network reachability","Validate table metadata integrity (attempt a metadata table read)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// probe the table before planning\nboolean reachable = fileIO.newInputFile(table.location() + \"/metadata\").exists();","typeGuard":null,"tryCatchPattern":"try { scan.tasks(); } catch (UncheckedIOException e) { retryWithBackoff(e.getCause()); }","preventionTips":["Configure retries/throttling on storage clients","Validate credentials before query execution","Monitor manifest/metadata file health"],"tags":["spark","iceberg","io-exception","scan-planning"],"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"}