apache/iceberg · error · IllegalArgumentException

Unknown manifest content: ${content}

Error message

Unknown manifest content: ${content}

What it means

RewriteManifestsSparkAction.loadManifests selects manifest lists from a snapshot by manifest content type (DATA or DELETES). If the snapshot's ManifestContent enum is anything else, it throws IllegalArgumentException. In practice this only occurs with future/unknown content types from a newer spec version.

Source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/actions/RewriteManifestsSparkAction.java:371

    if (currentSnapshot == null) {
      return ImmutableList.of();
    }

    List<ManifestFile> manifests = loadManifests(content, currentSnapshot);

    return manifests.stream()
        .filter(manifest -> manifest.partitionSpecId() == spec.specId() && predicate.test(manifest))
        .collect(Collectors.toList());
  }

  private List<ManifestFile> loadManifests(ManifestContent content, Snapshot snapshot) {
    switch (content) {
      case DATA:
        return snapshot.dataManifests(table.io());
      case DELETES:
        return snapshot.deleteManifests(table.io());
      default:
        throw new IllegalArgumentException("Unknown manifest content: " + content);
    }
  }

  private int targetNumManifests(long totalSizeBytes) {
    return (int) ((totalSizeBytes + targetManifestSizeBytes - 1) / targetManifestSizeBytes);
  }

  private long totalSizeBytes(Iterable<ManifestFile> manifests) {
    long totalSizeBytes = 0L;

    for (ManifestFile manifest : manifests) {
      ValidationException.check(
          hasFileCounts(manifest), "No file counts in manifest: %s", manifest.path());
      totalSizeBytes += manifest.length();
    }

    return totalSizeBytes;
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade the Spark Iceberg runtime to match (or exceed) the version that wrote the table metadata.
  2. Rewrite from a snapshot/version that only contains DATA and DELETES manifests (rollback or rewrite from an earlier version).
  3. Check the table's snapshots for unexpected manifest content with SparkActions before running rewrite.

Example fix

// before
sparkActions.rewriteManifests(table).execute();
// after
// upgrade runtime first, then:
sparkActions.rewriteManifests(table).useSnapshotId(validSnapshotId).execute();
Defensive patterns

Strategy: type-guard

Validate before calling

boolean ok = table.currentSnapshot() == null || table.currentSnapshot().allManifests(table.io()).stream().allMatch(m -> m.content() == ManifestContent.DATA || m.content() == ManifestContent.DELETES);

Type guard

if (manifest.content() != ManifestContent.DATA && manifest.content() != ManifestContent.DELETES) { throw new IllegalArgumentException(...); }

Try / catch

try { action.execute(); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unknown manifest content")) { /* upgrade runtime / use different snapshot */ } else throw e; }

Prevention

When it happens

Trigger: Calling RewriteManifestsSparkAction.execute() on a table whose snapshot contains a manifest with a content type other than DATA or DELETES (e.g. written by a newer Iceberg spec with an added content type).

Common situations: Reading tables produced by a newer Iceberg version with an older Spark runtime; corrupted or hand-edited metadata assigning an unexpected content value.

Related errors


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