apache/iceberg · error · UnsupportedOperationException

Unsupported content:

Error message

Unsupported content: 

What it means

When building the DeleteFileIndex, each delete file is dispatched by its FileContent. POSITION_DELETES and EQUALITY_DELETES are handled; any other content (which should not appear in a delete index) hits the default branch and throws UnsupportedOperationException with the file's content value.

Source

Thrown at core/src/main/java/org/apache/iceberg/DeleteFileIndex.java:554

      PartitionMap<EqualityDeletes> eqDeletesByPartition = PartitionMap.create(specsById);
      PartitionMap<PositionDeletes> posDeletesByPartition = PartitionMap.create(specsById);
      Map<String, PositionDeletes> posDeletesByPath = Maps.newHashMap();
      Map<String, DeleteFile> dvByPath = Maps.newHashMap();

      for (DeleteFile file : files) {
        switch (file.content()) {
          case POSITION_DELETES:
            if (ContentFileUtil.isDV(file)) {
              add(dvByPath, file);
            } else {
              add(posDeletesByPath, posDeletesByPartition, file);
            }
            break;
          case EQUALITY_DELETES:
            add(globalDeletes, eqDeletesByPartition, file, fieldLookup);
            break;
          default:
            throw new UnsupportedOperationException("Unsupported content: " + file.content());
        }
        ScanMetricsUtil.indexedDeleteFile(scanMetrics, file);
      }

      return new DeleteFileIndex(
          globalDeletes.isEmpty() ? null : globalDeletes,
          eqDeletesByPartition.isEmpty() ? null : eqDeletesByPartition,
          posDeletesByPartition.isEmpty() ? null : posDeletesByPartition,
          posDeletesByPath.isEmpty() ? null : posDeletesByPath,
          dvByPath.isEmpty() ? null : dvByPath,
          specsById.isEmpty() ? null : specsById);
    }

    private void add(Map<String, DeleteFile> dvByPath, DeleteFile dv) {
      String path = dv.referencedDataFile();
      DeleteFile existingDV = dvByPath.putIfAbsent(path, dv);
      if (existingDV != null) {
        throw new ValidationException(

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Find the offending file/content value in the message and inspect its manifest.
  2. Regenerate or rewrite the affected manifest with valid delete content values.
  3. Ensure only delete manifests (position/equality) are passed to the delete index.
  4. Validate metadata producers — content must be 1 or 2 for delete files.

Example fix

// before
index.addFiles(dataManifestEntries); // includes DATA files
// after
index.addFiles(entries.filter(e -> e.file().content() != FileContent.DATA));
Defensive patterns

Strategy: validation

Validate before calling

entries.forEach(e -> Preconditions.check(
    e.file().content() == FileContent.POSITION_DELETES || e.file().content() == FileContent.EQUALITY_DELETES,
    "non-delete content in delete index: " + e.file().content()));

Try / catch

try { DeleteFileIndex idx = DeleteFileIndex.buildFor(...); } catch (UnsupportedOperationException e) {
  LOG.error("bad content value", e);
  throw e;
}

Prevention

When it happens

Trigger: Constructing DeleteFileIndex.build with a delete manifest entry whose content is DATA (0) or an unknown/invalid content value — e.g. corrupt metadata, wrong manifest passed in, or a spec-version mismatch producing misread content.

Common situations: Corrupted or hand-edited manifests; custom catalog tooling writing invalid content values; reading metadata written by a nonconformant producer.

Related errors


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