apache/iceberg · error · UnsupportedOperationException

Cannot apply unknown table change

Error message

Cannot apply unknown table change: ${change}

What it means

Thrown by Spark3Util.applyPropertyChanges when a Spark TableChange is neither SetProperty nor RemoveProperty. Only property changes may be passed to this method; any other change type cannot be applied to a PendingUpdate for properties.

Solutions

  1. Filter the change list to instanceof SetProperty/RemoveProperty before calling applyPropertyChanges
  2. Route non-property changes (schema changes) to applySchemaChanges instead
  3. Log/inspect the change object to find which type slipped through

Example fix

// before
Spark3Util.applyPropertyChanges(update, changes);
// after
List<TableChange> propChanges = Arrays.stream(changes)
    .filter(c -> c instanceof TableChange.SetProperty || c instanceof TableChange.RemoveProperty)
    .collect(Collectors.toList());
Spark3Util.applyPropertyChanges(update, propChanges);
Defensive patterns

Strategy: type-guard

Validate before calling

boolean allPropertyChanges = Arrays.stream(changes)
    .allMatch(c -> c instanceof TableChange.SetProperty || c instanceof TableChange.RemoveProperty);

Type guard

boolean isPropertyChange(TableChange c) {
  return c instanceof TableChange.SetProperty || c instanceof TableChange.RemoveProperty;
}

Try / catch

try {
  Spark3Util.applyPropertyChanges(update, changes);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("Cannot apply unknown table change")) {
    // split changes and route each to the right handler
  }
}

Prevention

When it happens

Trigger: Calling Spark3Util.applyPropertyChanges with a TableChange that is not SetProperty/RemoveProperty, e.g. an AddColumn, DeleteColumn, or UpdateColumnComment leaking into the property-change path.

Common situations: Custom catalog or engine integration code that splits an ALTER TABLE change list incorrectly; passing the full change array instead of filtering to property changes first.

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/4a59c1772a9ad380. Report an issue: GitHub.

Appendix: source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:169

   * Applies a list of Spark table changes to an {@link UpdateProperties} operation.
   *
   * @param pendingUpdate an uncommitted UpdateProperties operation to configure
   * @param changes a list of Spark table changes
   * @return the UpdateProperties operation configured with the changes
   */
  public static UpdateProperties applyPropertyChanges(
      UpdateProperties pendingUpdate, List<TableChange> changes) {
    for (TableChange change : changes) {
      if (change instanceof TableChange.SetProperty) {
        TableChange.SetProperty set = (TableChange.SetProperty) change;
        pendingUpdate.set(set.property(), set.value());

      } else if (change instanceof TableChange.RemoveProperty) {
        TableChange.RemoveProperty remove = (TableChange.RemoveProperty) change;
        pendingUpdate.remove(remove.property());

      } else {
        throw new UnsupportedOperationException("Cannot apply unknown table change: " + change);
      }
    }

    return pendingUpdate;
  }

  /**
   * Applies a list of Spark table changes to an {@link UpdateSchema} operation.
   *
   * @param pendingUpdate an uncommitted UpdateSchema operation to configure
   * @param changes a list of Spark table changes
   * @return the UpdateSchema operation configured with the changes
   */
  public static UpdateSchema applySchemaChanges(
      UpdateSchema pendingUpdate, List<TableChange> changes) {
    for (TableChange change : changes) {
      if (change instanceof TableChange.AddColumn) {
        apply(pendingUpdate, (TableChange.AddColumn) change);

View on GitHub (pinned to 86d9c8fc54)