apache/iceberg · error · UncheckedIOException

Failed to read manifest:

Error message

Failed to read manifest: 

What it means

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.

Source

Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/EqualityConvertDVWriter.java:312

    }

    return anyPartition;
  }

  private void readDVEntries(
      ManifestFile manifest, Set<String> filterPaths, Map<String, DeleteFile> out) {
    manifestsRead++;
    try (ManifestReader<DeleteFile> reader =
        ManifestFiles.readDeleteManifest(manifest, table.io(), table.specs())) {
      for (DeleteFile deleteFile : reader) {
        if (ContentFileUtil.isDV(deleteFile)
            && deleteFile.referencedDataFile() != null
            && filterPaths.contains(deleteFile.referencedDataFile())) {
          out.put(deleteFile.referencedDataFile(), deleteFile);
        }
      }
    } catch (IOException e) {
      throw new UncheckedIOException("Failed to read manifest: " + manifest.path(), e);
    }
  }

  @VisibleForTesting
  int manifestsReadLastCycle() {
    return manifestsRead;
  }

  @VisibleForTesting
  int retainedStateSize() {
    return positionsByFile.size();
  }

  private PositionDeleteIndex loadPreviousDV(String dataFilePath, Map<String, DeleteFile> dvs) {
    DeleteFile existingDV = dvs.get(dataFilePath);
    if (existingDV == null) {
      return null;
    }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Retry the cycle — transient storage errors often clear on the next attempt.
  2. Stop concurrent expireSnapshots/orphan-file deletion while the converter runs.
  3. Verify FileIO credentials/permissions allow reading manifests in the table location.
  4. Check the wrapped IOException cause for storage-specific errors (403, 404, throttling) and fix storage config accordingly.

Example fix

// before
TableMaintenance.forTable(table).run();
ExpireSnapshots expire = table.expireSnapshots();
expire.execute();  // concurrent expiry removed manifests mid-cycle
// after
// run expiry only after/away from the maintenance cycle
if (!maintenanceRunning) {
  table.expireSnapshots().execute();
}
TableMaintenance.forTable(table).run();
Defensive patterns

Strategy: retry

Validate before calling

// probe manifest readability before planning
try (CloseableIterable<AutoCloseable> ignored =
         CloseableIterable.combine(ManifestFiles.read(manifest, table.io()).entries(), manifest)) {
  // readable
} catch (IOException e) {
  throw new IllegalStateException("Manifest unreadable before cycle: " + manifest.path(), e);
}

Try / catch

try {
  collectExistingDVs(snapshot);
} catch (UncheckedIOException e) {
  if (e.getMessage().startsWith("Failed to read manifest:")) {
    LOG.warn("Retrying DV collection after manifest read failure", e.getCause());
    retryWithBackoff(() -> collectExistingDVs(snapshot));
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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/296cb1251bb607fe. Report an issue: GitHub.