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
- Filter the change list to instanceof SetProperty/RemoveProperty before calling applyPropertyChanges
- Route non-property changes (schema changes) to applySchemaChanges instead
- 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
- Partition the change list by type before dispatching
- Log change.getClass().getName() when routing
- Cover change routing with unit tests for every TableChange subtype
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
- Cannot apply unknown table change
- 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
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)