{"record":{"id":"b2adc92ed7a99c5d","repo":"apache/iceberg","slug":"failed-to-close-parallel-iterable","errorCode":null,"errorMessage":"Failed to close parallel iterable","messagePattern":"Failed to close parallel iterable","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/apache/iceberg/BaseAllMetadataTableScan.java","lineNumber":84,"sourceCode":"        \"Scanning metadata table {} with filter {}.\",\n        metadataTableName,\n        ExpressionUtil.toSanitizedString(filter()));\n    Listeners.notifyAll(new ScanEvent(metadataTableName, 0L, filter(), schema()));\n\n    return doPlanFiles();\n  }\n\n  protected CloseableIterable<ManifestFile> reachableManifests(\n      Function<Snapshot, Iterable<ManifestFile>> toManifests) {\n    Iterable<Snapshot> snapshots = table().snapshots();\n    Iterable<Iterable<ManifestFile>> manifestIterables =\n        Iterables.transform(snapshots, toManifests);\n\n    try (CloseableIterable<ManifestFile> iterable =\n        new ParallelIterable<>(manifestIterables, planExecutor())) {\n      return CloseableIterable.withNoopClose(Sets.newHashSet(iterable));\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to close parallel iterable\", e);\n    }\n  }\n}\n","sourceCodeStart":66,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/BaseAllMetadataTableScan.java#L66-L88","documentation":"In reachableManifests(), if closing the ParallelIterable of manifest iterables fails with IOException, it is rethrown as UncheckedIOException with 'Failed to close parallel iterable'. This is a cleanup-path failure: the manifests themselves were being gathered via a parallel executor and closing the composite CloseableIterable raised. It usually indicates an underlying IO problem in a worker task's close routine.","triggerScenarios":"Planning an all_* metadata table scan over many snapshots where one ParallelIterable worker's underlying manifest iterator throws IOException during close().","commonSituations":"Object-store connection resets during task teardown; executor shutdown racing with close; disk/network failures while draining streams.","solutions":["Inspect the cause IOException in the UncheckedIOException for the real storage error","Retry the scan; transient storage faults often resolve","Check planExecutor thread-pool health and sizing","Verify storage endpoint stability/credentials for manifest list reads"],"exampleFix":"// before\nIterable<ManifestFile> manifests = scan.reachableManifests(); // throws UncheckedIOException on close\n// after\ntry {\n  Iterable<ManifestFile> manifests = scan.reachableManifests();\n} catch (UncheckedIOException e) {\n  LOG.warn(\"Retrying after close failure\", e.getCause());\n  manifests = scan.reachableManifests(); // transient IO during close\n}","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try { manifests = scan.reachableManifests(); } catch (UncheckedIOException e) { Throwable c = e.getCause(); /* inspect and retry if transient */ }","preventionTips":["Ensure the planning executor is properly sized and healthy","Watch for object-store connection instability","Retry transient IO faults during scans","Keep manifest lists local/replicated where possible"],"tags":["io","parallelism","close"],"backgroundTag":"broken-pipe","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"}