apache/iceberg · error · UnsupportedOperationException

Cannot apply unknown table change:

Error message

Cannot apply unknown table change: 

What it means

Thrown when Spark3Util.applyPropertyChanges encounters a Spark TableChange type it does not handle. Only SetProperty/RemoveProperty are supported for property updates; any other change type reaches the fallback branch.

Source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/Spark3Util.java:159

   * 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 schema change types (AddColumn/UpdateColumn/etc.) to applySchemaChanges instead
  2. Only pass SetProperty/RemoveProperty changes to applyPropertyChanges
  3. Upgrade Iceberg to a version supporting the new change type

Example fix

// before
spark3Util.applyPropertyChanges(update, allChanges);
// after
spark3Util.applyPropertyChanges(update, changes.filter(c -> c instanceof SetProperty || c instanceof RemoveProperty));
Defensive patterns

Strategy: type-guard

Validate before calling

List<TableChange> safe = changes.stream().filter(c -> c instanceof SetProperty || c instanceof RemoveProperty).collect(toList()); if (safe.size() != changes.size()) { /* route others to applySchemaChanges */ }

Type guard

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

Try / catch

try { applyPropertyChanges(update, changes); } catch (UnsupportedOperationException e) { LOG.error("Unroutable table change: {}", e.getMessage()); throw e; }

Prevention

When it happens

Trigger: Passing a mixed list of TableChange objects (schema changes included) to applyPropertyChanges, or a new Spark TableChange subtype introduced in a newer Spark version.

Common situations: ALTER TABLE SET TBLPROPERTIES mixed via generic change APIs; custom catalogs funneling all changes through one helper; Spark upgrade adding new TableChange subclasses not yet mapped.

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