apache/iceberg · error · UnsupportedOperationException

Cannot write manifest for table version

Error message

Cannot write manifest for table version: %s

What it means

ManifestFiles.newWriter only supports manifest writers for table format versions 1 through 4 (via a switch); any other formatVersion falls through to this UnsupportedOperationException. It guards against writing manifests for table versions the library cannot emit.

Solutions

  1. Upgrade the Iceberg library so it supports the table's format version
  2. Pass formatVersion 1-4 (matching the table's format-version property) when creating writers manually
  3. Do not mix older clients with tables using newer format versions

Example fix

// before
ManifestFiles.write(5, spec, outputFile, snapshotId);
// after
ManifestFiles.write(2, spec, outputFile, snapshotId);
Defensive patterns

Strategy: validation

Validate before calling

int fv = table.ops().current().formatVersion();
if (fv < 1 || fv > 4) {
  throw new IllegalStateException("Unsupported format version for manifest write: " + fv);
}

Try / catch

try {
  ManifestFiles.write(formatVersion, spec, outputFile, snapshotId);
} catch (UnsupportedOperationException e) {
  LOG.error("Format version {} not supported by this Iceberg build", formatVersion, e);
}

Prevention

When it happens

Trigger: Calling ManifestFiles.write or newWriter with a formatVersion outside 1-4, e.g., 0 or 5.

Common situations: Reading a table written by a newer Iceberg release supporting a higher format version with an older client; constructing writers with a hand-set formatVersion; corrupted metadata carrying an out-of-range version.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/ManifestFiles.java:284

      int formatVersion,
      PartitionSpec spec,
      EncryptedOutputFile encryptedOutputFile,
      Long snapshotId,
      Long firstRowId,
      Map<String, String> writerProperties) {
    switch (formatVersion) {
      case 1:
        return new ManifestWriter.V1Writer(spec, encryptedOutputFile, snapshotId, writerProperties);
      case 2:
        return new ManifestWriter.V2Writer(spec, encryptedOutputFile, snapshotId, writerProperties);
      case 3:
        return new ManifestWriter.V3Writer(
            spec, encryptedOutputFile, snapshotId, firstRowId, writerProperties);
      case 4:
        return new ManifestWriter.V4Writer(
            spec, encryptedOutputFile, snapshotId, firstRowId, writerProperties);
    }
    throw new UnsupportedOperationException(
        "Cannot write manifest for table version: " + formatVersion);
  }

  /**
   * Returns a new {@link ManifestReader} for a {@link ManifestFile}.
   *
   * @param manifest a {@link ManifestFile}
   * @param io a {@link FileIO}
   * @param specsById a Map from spec ID to partition spec
   * @return a {@link ManifestReader}
   */
  public static ManifestReader<DeleteFile> readDeleteManifest(
      ManifestFile manifest, FileIO io, Map<Integer, PartitionSpec> specsById) {
    Preconditions.checkArgument(
        manifest.content() == ManifestContent.DELETES,
        "Cannot read a data manifest with a DeleteManifestReader: %s",
        manifest);
    InputFile file = newInputFile(io, manifest);

View on GitHub (pinned to 86d9c8fc54)