{"record":{"id":"296cb1251bb607fe","repo":"apache/iceberg","slug":"failed-to-read-manifest-296cb1","errorCode":null,"errorMessage":"Failed to read manifest: ","messagePattern":"Failed to read manifest: ","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"flink/v2.2/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.2/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/EqualityConvertDVWriter.java#L294-L330","documentation":"readDVEntries opens a manifest via the table's FileIO and iterates its delete-file entries to collect existing deletion vectors. Any IOException (unreadable file, deleted object, I/O error from the object store or HDFS) is wrapped in UncheckedIOException naming the manifest path. This means the planner's DV collection step could not read a manifest that is still referenced by the snapshot.","triggerScenarios":"collectExistingDVs -> readDVEntries reads a manifest whose underlying file is missing, deleted (e.g., after snapshot expiry raced the maintenance job), or temporarily unreachable in the object store/HDFS.","commonSituations":"Snapshot expiration or orphan-file cleanup deleting manifests while the maintenance job runs; transient S3/GCS/ADLS 5xx or throttling errors; HDFS NameNode unavailability; wrong FileIO credentials so reads are denied.","solutions":["Retry the cycle — transient storage errors often clear on the next attempt.","Stop concurrent expireSnapshots/orphan-file deletion while the converter runs.","Verify FileIO credentials/permissions allow reading manifests in the table location.","Check the wrapped IOException cause for storage-specific errors (403, 404, throttling) and fix storage config accordingly."],"exampleFix":"// before\nTableMaintenance.forTable(table).run();\nExpireSnapshots expire = table.expireSnapshots();\nexpire.execute();  // concurrent expiry removed manifests mid-cycle\n// after\n// run expiry only after/away from the maintenance cycle\nif (!maintenanceRunning) {\n  table.expireSnapshots().execute();\n}\nTableMaintenance.forTable(table).run();","handlingStrategy":"retry","validationCode":"// probe manifest readability before planning\ntry (CloseableIterable<AutoCloseable> ignored =\n         CloseableIterable.combine(ManifestFiles.read(manifest, table.io()).entries(), manifest)) {\n  // readable\n} catch (IOException e) {\n  throw new IllegalStateException(\"Manifest unreadable before cycle: \" + manifest.path(), e);\n}","typeGuard":null,"tryCatchPattern":"try {\n  collectExistingDVs(snapshot);\n} catch (UncheckedIOException e) {\n  if (e.getMessage().startsWith(\"Failed to read manifest:\")) {\n    LOG.warn(\"Retrying DV collection after manifest read failure\", e.getCause());\n    retryWithBackoff(() -> collectExistingDVs(snapshot));\n  } else {\n    throw e;\n  }\n}","preventionTips":["Do not run expireSnapshots/orphan cleanup concurrently with the converter.","Validate storage credentials and network path to the object store before long cycles.","Use retries with backoff for transient storage errors.","Monitor object-store 5xx/throttling metrics during maintenance windows."],"tags":["io","manifest","file-read","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"}