apache/iceberg · error · RuntimeIOException

Cannot read manifest list file: %s

Error message

Cannot read manifest list file: %s

What it means

Thrown when reading a manifest list (snapshot list) Avro file fails with an IOException. ManifestLists.read opens the file via the table's FileIO and projects the ManifestFile schema; any I/O failure while opening or reading is wrapped in RuntimeIOException.

Source

Thrown at core/src/main/java/org/apache/iceberg/ManifestLists.java:56

      return ManifestFiles.contentCache(io).tryCache(input);
    }

    return input;
  }

  static List<ManifestFile> read(InputFile manifestList) {
    try (CloseableIterable<ManifestFile> files =
        InternalData.read(FileFormat.AVRO, manifestList)
            .setRootType(GenericManifestFile.class)
            .setCustomType(
                ManifestFile.PARTITION_SUMMARIES_ELEMENT_ID, GenericPartitionFieldSummary.class)
            .project(ManifestFile.schema())
            .build()) {

      return Lists.newArrayList(files);

    } catch (IOException e) {
      throw new RuntimeIOException(
          e, "Cannot read manifest list file: %s", manifestList.location());
    }
  }

  static ManifestListWriter write(
      int formatVersion,
      OutputFile manifestListFile,
      EncryptionManager encryptionManager,
      long snapshotId,
      Long parentSnapshotId,
      long sequenceNumber,
      Long firstRowId) {
    switch (formatVersion) {
      case 1:
        Preconditions.checkArgument(
            sequenceNumber == TableMetadata.INITIAL_SEQUENCE_NUMBER,
            "Invalid sequence number for v1 manifest list: %s",
            sequenceNumber);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check the wrapped IOException cause for file-not-found vs. access/network error.
  2. Verify the file still exists at the location in the snapshot metadata; if deleted by expiration, restore from backup or roll back the table.
  3. Confirm encryption keys and FileIO config match those used at write time.
  4. Retry on transient network/object-store errors.

Example fix

// before: aggressive expire before dependent readers finish
expiringSnapshots.expireOlderThan(System.currentTimeMillis());
// after: retain snapshots newer than the oldest active reader table's current snapshot
long safeTs = oldestDependentSnapshotTs();
expiringSnapshots.expireOlderThan(safeTs);
Defensive patterns

Strategy: try-catch

Validate before calling

// check file exists and is readable before read
InputFile in = io.newInputFile(manifestListLocation);
if (!in.exists()) { throw new IllegalStateException("manifest list missing: " + manifestListLocation); }

Try / catch

try {
  List<ManifestFile> files = ManifestLists.read(io, manifestListLocation);
} catch (RuntimeIOException e) {
  if (causeIsNotFound(e)) handleMissingSnapshot(); // roll back / restore from backup
  else retry();
}

Prevention

When it happens

Trigger: SnapshotProducer/operations call ManifestLists.read(...) for a parent snapshot or during cleanup; the manifest list file cannot be opened or read (missing file, network error, decryption failure).

Common situations: Metadata file references a manifest list that was deleted (e.g., orphan cleanup ran concurrently, retention too aggressive); object store connectivity failure; wrong encryption key/key management config; corrupted file.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/98e890bb15e1793f. Report an issue: GitHub.