{"record":{"id":"010d9fd711ac5b34","repo":"apache/iceberg","slug":"failed-to-close-entries-while-caching-changes","errorCode":null,"errorMessage":"Failed to close entries while caching changes","messagePattern":"Failed to close entries while caching changes","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/BaseSnapshot.java","lineNumber":324,"sourceCode":"        Iterables.filter(\n            dataManifests(fileIO), manifest -> Objects.equal(manifest.snapshotId(), snapshotId));\n    try (CloseableIterable<ManifestEntry<DataFile>> entries =\n        new ManifestGroup(fileIO, changedManifests).ignoreExisting().entries()) {\n      for (ManifestEntry<DataFile> entry : 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            throw new IllegalStateException(\n                \"Unexpected entry status, not added or deleted: \" + entry);\n        }\n      }\n    } catch (IOException e) {\n      throw new RuntimeIOException(e, \"Failed to close entries while caching changes\");\n    }\n\n    this.addedDataFiles = adds.build();\n    this.removedDataFiles = deletes.build();\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (this == o) {\n      return true;\n    }\n\n    if (o instanceof BaseSnapshot) {\n      BaseSnapshot other = (BaseSnapshot) o;\n      return this.snapshotId == other.snapshotId()\n          && Objects.equal(this.parentId, other.parentId())\n          && this.sequenceNumber == other.sequenceNumber()\n          && this.timestampMillis == other.timestampMillis()","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/BaseSnapshot.java#L306-L342","documentation":"A sibling of the reader-close failure on the data path: while caching data-file changes, closing the ManifestReader after iteration throws an IOException, which Iceberg converts to RuntimeIOException with message \"Failed to close entries while caching changes\".","triggerScenarios":"Calling addedDataFiles()/removedDataFiles() when the underlying object store fails while closing the manifest reader: connection reset, credentials expiring mid-scan, or the manifest being deleted concurrently.","commonSituations":"Long-running incremental-scan jobs whose cloud credentials expire; S3/GCS throttling; cleanup jobs removing manifests mid-read.","solutions":["Retry the call after table.refresh(); typically transient","Ensure credentials/Tokens are valid for the duration of the scan (refresh STS tokens, session tokens)","Prevent expireSnapshots/orphan cleanup from racing with incremental change readers","Check storage backend health and network stability"],"exampleFix":"// before\nList<DataFile> added = snapshot.addedDataFiles();\n// after\ntry {\n  List<DataFile> added = snapshot.addedDataFiles();\n} catch (RuntimeIOException e) {\n  table.refresh();\n  List<DataFile> added = snapshot.addedDataFiles();\n}","handlingStrategy":"try-catch","validationCode":"// ensure credentials valid for scan duration\nif (credentialsExpiryEpochMs < System.currentTimeMillis() + scanDurationMs) refreshCredentials();","typeGuard":null,"tryCatchPattern":"try { snapshot.addedDataFiles(); } catch (RuntimeIOException e) { table.refresh(); retryWithBackoff(); }","preventionTips":["Use long-lived or auto-refreshing credentials for long incremental scans","Configure FileIO retry/throttle settings for the cloud backend","Exclude cleanup jobs from running concurrently with change caching"],"tags":["iceberg","io","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"}