{"record":{"id":"f3f044aa1db090f7","repo":"apache/iceberg","slug":"failed-to-read-manifest-file-s-f3f044","errorCode":null,"errorMessage":"Failed to read manifest file: %s","messagePattern":"Failed to read manifest file: (.+?)","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/ReachableFileCleanup.java","lineNumber":190,"sourceCode":"      Set<ManifestFile> currentManifestFiles,\n      Map<Integer, PartitionSpec> specsById) {\n    Set<String> filesToDelete = ConcurrentHashMap.newKeySet();\n\n    Tasks.foreach(manifestFilesToDelete)\n        .retry(3)\n        .suppressFailureWhenFinished()\n        .executeWith(planExecutorService)\n        .onFailure(\n            (item, exc) ->\n                LOG.warn(\n                    \"Failed to determine live files in manifest {}. Retrying\", item.path(), exc))\n        .run(\n            manifest -> {\n              try (CloseableIterable<String> paths =\n                  ManifestFiles.readPaths(manifest, fileIO, specsById)) {\n                paths.forEach(filesToDelete::add);\n              } catch (IOException e) {\n                throw new RuntimeIOException(e, \"Failed to read manifest file: %s\", manifest);\n              }\n            });\n\n    if (filesToDelete.isEmpty()) {\n      return filesToDelete;\n    }\n\n    try {\n      Tasks.foreach(currentManifestFiles)\n          .retry(3)\n          .stopOnFailure()\n          .throwFailureWhenFinished()\n          .executeWith(planExecutorService)\n          .onFailure(\n              (item, exc) ->\n                  LOG.warn(\n                      \"Failed to determine live files in manifest {}. Retrying\", item.path(), exc))\n          .run(","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/ReachableFileCleanup.java#L172-L208","documentation":"In ReachableFileCleanup.findFilesToDelete, ManifestFiles.readPaths streams data-file paths from each manifest to build the set of files eligible for deletion. An IOException during that read is rethrown as RuntimeIOException naming the manifest. It indicates the manifest file could not be read.","triggerScenarios":"expireSnapshots with file cleanup: reading paths from a candidate manifest (to decide which data files to delete) fails with IOException from the underlying FileIO.","commonSituations":"Corrupted or truncated manifest files; object-store outages or throttling during expiration; externally deleted manifest objects; permission/credential misconfiguration on the table location.","solutions":["Check that the reported manifest file exists and is readable in the object store; restore it if externally deleted","Retry the expiration after resolving storage connectivity/throttling issues","Validate FileIO credentials and permissions for the table's data/metadata paths"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check manifest readability before cleanup\nManifestFile m = /* manifest from snapshot */;\nPreconditions.checkArgument(io.newInputFile(m.path()).exists(), \"Missing manifest: \" + m.path());","typeGuard":null,"tryCatchPattern":"try {\n  expireSnapshots(table).cleanExpiredFiles(true).execute();\n} catch (RuntimeIOException e) {\n  // message names the unreadable manifest; verify/restore it, then retry\n}","preventionTips":["Never remove manifest files outside of Iceberg operations","Validate storage permissions for metadata paths before cleanup","Handle object-store throttling with retries","Back up the metadata directory before expiration"],"tags":["iceberg","io","manifest","snapshot-expiration"],"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"}