{"record":{"id":"f4ca5cb166241aa2","repo":"apache/iceberg","slug":"failed-to-read-manifest","errorCode":null,"errorMessage":"Failed to read manifest: ","messagePattern":"Failed to read manifest: ","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/EqualityConvertDVWriter.java","lineNumber":312,"sourceCode":"    }\n\n    return anyPartition;\n  }\n\n  private void readDVEntries(\n      ManifestFile manifest, Set<String> filterPaths, Map<String, DeleteFile> out) {\n    manifestsRead++;\n    try (ManifestReader<DeleteFile> reader =\n        ManifestFiles.readDeleteManifest(manifest, table.io(), table.specs())) {\n      for (DeleteFile deleteFile : reader) {\n        if (ContentFileUtil.isDV(deleteFile)\n            && deleteFile.referencedDataFile() != null\n            && filterPaths.contains(deleteFile.referencedDataFile())) {\n          out.put(deleteFile.referencedDataFile(), deleteFile);\n        }\n      }\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to read manifest: \" + manifest.path(), e);\n    }\n  }\n\n  @VisibleForTesting\n  int manifestsReadLastCycle() {\n    return manifestsRead;\n  }\n\n  @VisibleForTesting\n  int retainedStateSize() {\n    return positionsByFile.size();\n  }\n\n  private PositionDeleteIndex loadPreviousDV(String dataFilePath, Map<String, DeleteFile> dvs) {\n    DeleteFile existingDV = dvs.get(dataFilePath);\n    if (existingDV == null) {\n      return null;\n    }","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/EqualityConvertDVWriter.java#L294-L330","documentation":"readDVEntries() iterates a manifest's delete files to collect existing deletion vectors; an IOException from opening/reading the manifest data is wrapped in UncheckedIOException with the manifest path. It means table metadata content could not be read from storage.","triggerScenarios":"readDVEntries called during collectExistingDVs while the underlying FileIO fails to open or stream the manifest file — deleted object, expired snapshot cleanup, credentials revoked, or transient S3/HDFS errors.","commonSituations":"Object store throttling or 5xx during manifest reads; snapshot expiration (orphan/expireSnapshots) removing a still-referenced manifest; missing/expired cloud credentials on TaskManagers; HDFS NameNode unavailability.","solutions":["Retry the maintenance task — most storage errors are transient","Verify the manifest still exists and wasn't removed by expireSnapshots running concurrently","Check FileIO credentials/permissions on the TaskManager for the table location","Inspect the cause (IOException chain) for the storage-level error (403, 404, timeout)","Enable retries on the object store client (S3 retry config, HDFS client settings)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// preflight: manifest reachable via FileIO\nboolean exists = table.io().newInputFile(manifestPath).exists();","typeGuard":null,"tryCatchPattern":"try {\n  planner.plan();\n} catch (UncheckedIOException e) {\n  if (e.getMessage().startsWith(\"Failed to read manifest: \")) {\n    // transient storage error: retry with backoff; else verify snapshot validity\n  } else { throw e; }\n}","preventionTips":["Don't run expireSnapshots concurrently with conversion","Use resilient object-store clients with retries","Keep credentials valid/refreshed on TaskManagers","Include the manifest path from the message when triaging storage logs"],"tags":["io","manifest","storage","deletion-vector","flink"],"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"}