apache/iceberg · error · java.lang.UnsupportedOperationException
Cannot apply unknown table change
Error message
Cannot apply unknown table change: <change>
What it means
SparkCatalog.alterTable iterates the incoming Spark TableChange list and classifies each change (property, location, snapshot, column). If a change is not a recognized Iceberg-supported type, it throws UnsupportedOperationException because Iceberg cannot translate that change into a metadata commit.
Solutions
- Check the change type you are passing is one Iceberg supports: SetProperty, RemoveProperty, LocationChange, SetSnapshotId, or ColumnChange subtypes
- Upgrade to a newer Iceberg version that may support the change kind
- Apply unsupported changes directly through the Iceberg API (table.updateSchema(), table.updateProperties()) instead of the Spark catalog
Example fix
// before
spark.sql("ALTER TABLE t SET TBLPROPERTIES ...") // with an unsupported change kind from a plugin
// after
Table table = sparkCatalog.icebergCatalog().loadTable(ident);
table.updateProperties().set("key", "value").commit(); Defensive patterns
Strategy: validation
Validate before calling
if (!(change instanceof SetProperty || change instanceof RemoveProperty || change instanceof ColumnChange || change instanceof LocationChange || change instanceof SetSnapshotId)) { throw new IllegalArgumentException("Unsupported change: " + change); } Type guard
boolean isSupported(TableChange c) { return c instanceof SetProperty || c instanceof RemoveProperty || c instanceof ColumnChange || c instanceof LocationChange || c instanceof SetSnapshotId; } Prevention
- Only construct TableChange instances from documented Iceberg-supported subtypes
- Validate changes with a type filter before passing to alterTable
- Keep Iceberg and Spark versions aligned so new TableChange kinds are mapped
When it happens
Trigger: Calling ALTER TABLE via Spark with a TableChange subtype Iceberg does not support, e.g. Spark's RemoveProperty variant not matching, or engine/plugin-generated custom TableChange instances passed to catalog().alterTable().
Common situations: Custom catalogs/plugins injecting new TableChange subtypes; Spark version upgrades adding new change kinds Iceberg hasn't mapped yet; programmatic use of the Spark catalog API with hand-built TableChange objects.
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
- Altering a view is not supported by catalog:
- Altering a view is not supported by catalog
- Altering a view is not supported by catalog
- Altering a view is not supported by catalog
- does not support altering tables
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/681ae9b7acefef58.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:308
} else if ("cherry-pick-snapshot-id".equalsIgnoreCase(set.property())) {
pickSnapshotId = set;
} else if ("sort-order".equalsIgnoreCase(set.property())) {
throw new UnsupportedOperationException(
"Cannot specify the 'sort-order' because it's a reserved table "
+ "property. Please use the command 'ALTER TABLE ... WRITE ORDERED BY' to specify write sort-orders.");
} else if ("identifier-fields".equalsIgnoreCase(set.property())) {
throw new UnsupportedOperationException(
"Cannot specify the 'identifier-fields' because it's a reserved table property. "
+ "Please use the command 'ALTER TABLE ... SET IDENTIFIER FIELDS' to specify identifier fields.");
} else {
propertyChanges.add(set);
}
} else if (change instanceof RemoveProperty) {
propertyChanges.add(change);
} else if (change instanceof ColumnChange) {
schemaChanges.add(change);
} else {
throw new UnsupportedOperationException("Cannot apply unknown table change: " + change);
}
}
try {
org.apache.iceberg.Table table = icebergCatalog.loadTable(buildIdentifier(ident));
commitChanges(
table, setLocation, setSnapshotId, pickSnapshotId, propertyChanges, schemaChanges);
return new SparkTable(table);
} catch (org.apache.iceberg.exceptions.NoSuchTableException e) {
throw new NoSuchTableException(ident);
}
}
@Override
public boolean dropTable(Identifier ident) {
return catalogDropTable(ident);
}
View on GitHub (pinned to 86d9c8fc54)