apache/iceberg · error · UnsupportedOperationException
Cannot apply unknown table change:
Error message
Cannot apply unknown table change:
What it means
The final else branch of applySchemaChanges rejects any TableChange type the util does not explicitly handle, preventing silent loss of schema updates. The thrown message includes the change's toString.
Solutions
- Upgrade iceberg-flink to a version handling the new change type
- Filter out unsupported TableChange instances before calling applySchemaChanges
- Apply the unhandled change through a different mechanism (raw Iceberg API, Spark)
- Log and ignore the change if it is semantically a no-op for Iceberg
Example fix
// before
FlinkAlterTableUtil.applySchemaChanges(table, changes);
// after
List<TableChange> supported = changes.stream().filter(c ->
c instanceof TableChange.AddColumn || c instanceof TableChange.DropColumn
|| c instanceof TableChange.SetOption /* ... */).collect(Collectors.toList());
FlinkAlterTableUtil.applySchemaChanges(table, supported); Defensive patterns
Strategy: validation
Validate before calling
Set<Class<?>> supported = Set.of(TableChange.AddColumn.class, TableChange.DropColumn.class,
TableChange.ModifyColumn.class, TableChange.AddUniqueConstraint.class,
TableChange.SetOption.class);
boolean allSupported = changes.stream().allMatch(c ->
supported.stream().anyMatch(s -> s.isInstance(c))); Try / catch
try {
FlinkAlterTableUtil.applySchemaChanges(table, changes);
} catch (UnsupportedOperationException e) {
// identify the offending change from the message and route it elsewhere
} Prevention
- Whitelist known TableChange types before applying
- Pin connector and Flink versions so available change types match
- Handle unknown changes explicitly rather than forwarding blindly
When it happens
Trigger: Passing a TableChange subclass not covered by the if/else chain (e.g. a new Flink TableChange type added in a newer Flink version) into applySchemaChanges.
Common situations: Upgrading Flink and using newly introduced TableChange types with an older Iceberg connector; generic DDL-application frameworks forwarding all changes blindly.
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 partition keys is not supported yet.
- Cannot apply unknown modify-column change:
- Cannot apply unknown modify-column-position change:
- Cannot create the table with 'connector'='iceberg' table…
- Cannot create the table with 'connector'='iceberg' table…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/a399e6c593525560.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java:149
} else if (change instanceof TableChange.DropColumn) {
TableChange.DropColumn dropColumn = (TableChange.DropColumn) change;
pendingUpdate.deleteColumn(dropColumn.getColumnName());
} else if (change instanceof TableChange.AddWatermark) {
throw new UnsupportedOperationException("Unsupported table change: AddWatermark.");
} else if (change instanceof TableChange.ModifyWatermark) {
throw new UnsupportedOperationException("Unsupported table change: ModifyWatermark.");
} else if (change instanceof TableChange.DropWatermark) {
throw new UnsupportedOperationException("Unsupported table change: DropWatermark.");
} else if (change instanceof TableChange.AddUniqueConstraint) {
TableChange.AddUniqueConstraint addPk = (TableChange.AddUniqueConstraint) change;
applyUniqueConstraint(pendingUpdate, addPk.getConstraint());
} else if (change instanceof TableChange.ModifyUniqueConstraint) {
TableChange.ModifyUniqueConstraint modifyPk = (TableChange.ModifyUniqueConstraint) change;
applyUniqueConstraint(pendingUpdate, modifyPk.getNewConstraint());
} else if (change instanceof TableChange.DropConstraint) {
throw new UnsupportedOperationException("Unsupported table change: DropConstraint.");
} else {
throw new UnsupportedOperationException("Cannot apply unknown table change: " + change);
}
}
}
private static void applyAddColumn(UpdateSchema pendingUpdate, TableChange.AddColumn addColumn) {
Column flinkColumn = addColumn.getColumn();
Preconditions.checkArgument(
FlinkCompatibilityUtil.isPhysicalColumn(flinkColumn),
"Unsupported table change: Adding computed column %s.",
flinkColumn.getName());
Type icebergType = FlinkSchemaUtil.convert(flinkColumn.getDataType().getLogicalType());
if (flinkColumn.getDataType().getLogicalType().isNullable()) {
pendingUpdate.addColumn(
flinkColumn.getName(), icebergType, flinkColumn.getComment().orElse(null));
} else {
pendingUpdate.addRequiredColumn(View on GitHub (pinned to 86d9c8fc54)