apache/iceberg · error · UnsupportedOperationException

Cannot apply unknown table change: ${change}

Error message

Cannot apply unknown table change: ${change}

What it means

applyPropertyChanges iterates Spark TableChange instances and forwards supported ones (SetProperty, RemoveProperty) to an Iceberg PendingUpdate. Any other TableChange subtype is rejected with UnsupportedOperationException because table-property updates cannot express it.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:155

   * 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)

Solutions

  1. Route non-property changes (AddColumn, UpdateColumnType, etc.) to Spark3Util.applySchemaChanges instead
  2. Filter the change list so only SetProperty/RemoveProperty reach applyPropertyChanges
  3. Check the Iceberg/Spark version — newer versions support more change types

Example fix

// before
Spark3Util.applyPropertyChanges(table, changes); // changes include UpdateColumnComment
// after
List<TableChange> props = changes.stream().filter(c -> c instanceof TableChange.SetProperty || c instanceof TableChange.RemoveProperty).collect(toList());
Spark3Util.applyPropertyChanges(table, props);
Defensive patterns

Strategy: type-guard

Validate before calling

List<TableChange> props = changes.stream().filter(c -> c instanceof TableChange.SetProperty || c instanceof TableChange.RemoveProperty).collect(Collectors.toList());
if (props.size() != changes.size()) throw new IllegalArgumentException("non-property changes must go through applySchemaChanges");

Type guard

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

Try / catch

try { Spark3Util.applyPropertyChanges(table, changes); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("Cannot apply unknown table change")) { /* split changes by type and route */ } else throw e; }

Prevention

When it happens

Trigger: ALTER TABLE ... SET TBLPROPERTIES / UNSET TBLPROPERTIES path receiving a TableChange other than SetProperty or RemoveProperty, e.g. an engine or framework submitting column/comment changes through the property-change application path.

Common situations: Framework code that batches arbitrary TableChange arrays and calls applyPropertyChanges for all of them instead of routing schema changes to applySchemaChanges.

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