apache/iceberg · error · ValidationException

Unexpected action type for Delta Lake: %s

Error message

Unexpected action type for Delta Lake: %s

What it means

Thrown by BaseSnapshotDeltaLakeTableAction when converting Delta Lake log actions into Iceberg DataFiles and an action object is neither an AddFile nor a RemoveFile. The Delta standalone log reader surfaced an action type this migration/snapshot procedure does not map, so conversion fails fast instead of producing a corrupt DataFile.

Source

Thrown at delta-lake/src/main/java/org/apache/iceberg/delta/BaseSnapshotDeltaLakeTableAction.java:356

  private DataFile buildDataFileFromAction(Action action, Table table) {
    PartitionSpec spec = table.spec();
    String path;
    long fileSize;
    Long nullableFileSize;
    Map<String, String> partitionValues;

    if (action instanceof AddFile) {
      AddFile addFile = (AddFile) action;
      path = addFile.getPath();
      nullableFileSize = addFile.getSize();
      partitionValues = addFile.getPartitionValues();
    } else if (action instanceof RemoveFile) {
      RemoveFile removeFile = (RemoveFile) action;
      path = removeFile.getPath();
      nullableFileSize = removeFile.getSize().orElse(null);
      partitionValues = removeFile.getPartitionValues();
    } else {
      throw new ValidationException(
          "Unexpected action type for Delta Lake: %s", action.getClass().getSimpleName());
    }

    String fullFilePath = getFullFilePath(path, deltaLog.getPath().toString());
    // For unpartitioned table, the partitionValues should be an empty map rather than null
    Preconditions.checkArgument(
        partitionValues != null,
        String.format("File %s does not specify a partitionValues", fullFilePath));

    FileFormat format = determineFileFormatFromPath(fullFilePath);
    InputFile file = deltaLakeFileIO.newInputFile(fullFilePath);
    if (!file.exists()) {
      throw new NotFoundException(
          "File %s is referenced in the logs of Delta Lake table at %s, but cannot be found in the storage",
          fullFilePath, deltaTableLocation);
    }

    // If the file size is not specified, the size should be read from the file

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade org.apache.iceberg:iceberg-delta-lake and the delta-standalone dependency to versions matching the Delta writer version of the table (check _delta_log protocol minWriterVersion/minReaderVersion).
  2. Inspect the table's _delta_log to identify which action types are present; filter or pre-process unsupported actions before snapshotting.
  3. If a legitimate action type is missing from the mapping, patch BaseSnapshotDeltaLakeTableAction.buildDataFileFromAction to handle it.
  4. As a workaround, rewrite/compact the Delta table with a tool version that emits only AddFile/RemoveFile actions, then rerun the snapshot.

Example fix

// before: unhandled action falls through
} else {
  throw new ValidationException("Unexpected action type for Delta Lake: %s", action.getClass().getSimpleName());
}
// after: upgrade delta-standalone so AddCDCFile etc. are mapped, e.g.
} else if (action instanceof io.delta.standalone.actions.AddCDCFile) {
  // map change-data-capture file or skip it intentionally
}
Defensive patterns

Strategy: validation

Validate before calling

if (!(action instanceof io.delta.standalone.actions.AddFile) && !(action instanceof io.delta.standalone.actions.RemoveFile)) {
  throw new IllegalStateException("Unsupported Delta action: " + action.getClass().getName());
}

Type guard

boolean isSupported(Action a) {
  return a instanceof AddFile || a instanceof RemoveFile;
}

Prevention

When it happens

Trigger: Calling SnapshotDeltaLakeTable/SnapshotDeltaLakeTableAction on a Delta table whose transaction log contains an action type other than AddFile or RemoveFile reaching buildDataFileFromAction (e.g. newly introduced Delta log entries, metadata/commit actions passed in by a newer delta-standalone reader, or CDC entries).

Common situations: Migrating Delta tables written by newer Delta Lake protocol versions than the delta-standalone library supports; plugin or fork code that feeds custom actions into dataFile(); protocol upgrade on the Delta table after an Iceberg snapshot job was pinned to an older delta-standalone version.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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