{"record":{"id":"7882d479d4dab75e","repo":"apache/iceberg","slug":"failed-to-close-manifest-reader","errorCode":null,"errorMessage":"Failed to close manifest reader","messagePattern":"Failed to close manifest reader","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/BaseSnapshot.java","lineNumber":290,"sourceCode":"            deleteManifests(fileIO), manifest -> Objects.equal(manifest.snapshotId(), snapshotId));\n\n    for (ManifestFile manifest : changedManifests) {\n      try (ManifestReader<DeleteFile> reader =\n          ManifestFiles.readDeleteManifest(manifest, fileIO, null)) {\n        for (ManifestEntry<DeleteFile> entry : reader.entries()) {\n          switch (entry.status()) {\n            case ADDED:\n              adds.add(entry.file().copy());\n              break;\n            case DELETED:\n              deletes.add(entry.file().copyWithoutStats());\n              break;\n            default:\n              // ignore existing\n          }\n        }\n      } catch (IOException e) {\n        throw new UncheckedIOException(\"Failed to close manifest reader\", e);\n      }\n    }\n\n    this.addedDeleteFiles = adds.build();\n    this.removedDeleteFiles = deletes.build();\n  }\n\n  private void cacheDataFileChanges(FileIO fileIO) {\n    Preconditions.checkArgument(fileIO != null, \"Cannot cache data file changes: FileIO is null\");\n\n    ImmutableList.Builder<DataFile> adds = ImmutableList.builder();\n    ImmutableList.Builder<DataFile> deletes = ImmutableList.builder();\n\n    // read only manifests that were created by this snapshot\n    Iterable<ManifestFile> changedManifests =\n        Iterables.filter(\n            dataManifests(fileIO), manifest -> Objects.equal(manifest.snapshotId(), snapshotId));\n    try (CloseableIterable<ManifestEntry<DataFile>> entries =","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/BaseSnapshot.java#L272-L308","documentation":"While caching delete-file changes, BaseSnapshot iterates manifests with a ManifestReader in try-with-resources; closing the reader throws an IOException. Iceberg wraps it in UncheckedIOException with message \"Failed to close manifest reader\" because the failure happens at cleanup time inside a method that cannot throw checked exceptions.","triggerScenarios":"Calling addedDeleteFiles()/removedDeleteFiles() on a v2 snapshot whose delete manifests cannot be read or closed — network failure to object storage mid-iteration, corrupted/truncated manifest file, or IO backend error on close.","commonSituations":"S3/GCS transient errors while reading incremental changes; manifests deleted by concurrent cleanup; truncated metadata files after an interrupted write.","solutions":["Retry after table.refresh(); the failure is usually transient IO","Verify the manifest files referenced by the snapshot exist and are readable via the FileIO","Restore metadata from backup if the manifest is truncated/corrupt (e.g. rewrite with the metadata JSON)","Exclude competing expire/cleanup jobs while incrementally scanning changes"],"exampleFix":"// before\nList<DeleteFile> adds = snapshot.addedDeleteFiles();\n// after\ntry {\n  List<DeleteFile> adds = snapshot.addedDeleteFiles();\n} catch (UncheckedIOException e) {\n  table.refresh();\n  List<DeleteFile> adds = snapshot.addedDeleteFiles(); // retry transient IO\n}","handlingStrategy":"try-catch","validationCode":"ManifestFile m = snapshot.deleteManifests(io).get(0);\nif (!io.newInputFile(m.path()).exists()) throw new IllegalStateException(\"delete manifest missing\");","typeGuard":null,"tryCatchPattern":"try { snapshot.addedDeleteFiles(); } catch (UncheckedIOException e) { table.refresh(); /* retry or repair metadata */ }","preventionTips":["Avoid expireSnapshots/cleanup racing with incremental change reads","Monitor storage for transient errors; configure FileIO retries","Keep metadata backups for repair after truncated writes"],"tags":["iceberg","io","manifest-reader","unchecked-exception"],"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"}