apache/iceberg · error · java.lang.UnsupportedOperationException
Altering schema is not supported in the old alterTable API.
Error message
Altering schema is not supported in the old alterTable API. To alter schema, use the other alterTable API and provide a list of TableChange's.
What it means
The deprecated/legacy Flink Catalog.alterTable(ObjectPath, CatalogTable, boolean) API cannot change a table's schema; FlinkCatalog.validateTableSchemaAndPartition compares the unresolved schemas of the existing and new CatalogTable and throws UnsupportedOperationException when they differ. Schema evolution must go through the TableChange-based alterTable API.
Source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/FlinkCatalog.java:478
try {
icebergCatalog.createTable(
toIdentifier(tablePath), icebergSchema, spec, location, properties.build());
} catch (AlreadyExistsException e) {
if (!ignoreIfExists) {
throw new TableAlreadyExistException(getName(), tablePath, e);
}
}
}
private boolean isReservedProperty(String prop) {
return FlinkCreateTableOptions.LOCATION_KEY.equalsIgnoreCase(prop)
|| FlinkCreateTableOptions.CONNECTOR_PROPS_KEY.equalsIgnoreCase(prop)
|| FlinkCreateTableOptions.SRC_CATALOG_PROPS_KEY.equalsIgnoreCase(prop);
}
private static void validateTableSchemaAndPartition(CatalogTable ct1, CatalogTable ct2) {
if (!Objects.equals(ct1.getUnresolvedSchema(), ct2.getUnresolvedSchema())) {
throw new UnsupportedOperationException(
"Altering schema is not supported in the old alterTable API. "
+ "To alter schema, use the other alterTable API and provide a list of TableChange's.");
}
validateTablePartition(ct1, ct2);
}
private static void validateTablePartition(CatalogTable ct1, CatalogTable ct2) {
if (!ct1.getPartitionKeys().equals(ct2.getPartitionKeys())) {
throw new UnsupportedOperationException("Altering partition keys is not supported yet.");
}
}
/**
* This alterTable API only supports altering table properties.
*
* <p>Support for adding/removing/renaming columns cannot be done by comparing CatalogTable
* instances, unless the Flink schema contains Iceberg column IDs.View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use the TableChange-based alterTable: ALTER TABLE in Flink SQL (ALTER TABLE t ADD (c INT)) or catalog.alterTable(path, List<TableChange>, ignoreIfNotExists) with UpdateRequirements/UpdateOptions as appropriate.
- If only properties changed, verify the schema is byte-identical so the legacy API is safe, or migrate the call anyway.
- Upgrade the caller to Flink's newer catalog API surface that supports TableChange.
Example fix
// before
catalog.alterTable(path, tableWithNewColumn, false);
// after
catalog.alterTable(path, java.util.Arrays.asList(TableChange.addColumn("c", DataTypes.INT())), false); Defensive patterns
Strategy: validation
Validate before calling
// compare schemas before legacy alterTable
if (!current.getUnresolvedSchema().equals(proposed.getUnresolvedSchema())) {
useTableChangeApi = true;
} Type guard
boolean schemaUnchanged(CatalogTable a, CatalogTable b) {
return java.util.Objects.equals(a.getUnresolvedSchema(), b.getUnresolvedSchema());
} Try / catch
try { catalog.alterTable(path, proposed, false); }
catch (UnsupportedOperationException e) {
// fall back to TableChange-based alterTable
catalog.alterTable(path, schemaChanges, false);
} Prevention
- Always prefer the TableChange-based alterTable API for schema work
- Never mutate a CatalogTable in place and pass it to the legacy alterTable
- Check the Flink version's catalog API; the legacy alterTable is properties-only
When it happens
Trigger: Calling alterTable(tablePath, newCatalogTable, ignoreIfNotExists) where newCatalogTable's unresolved schema differs from the current table's — e.g. adding, dropping, renaming, or retyping a column via full-table replacement.
Common situations: Older Flink job/framework code that still uses the legacy alterTable signature to add a column; hand-written migration scripts that rewrite the whole CatalogTable; upgrading code written before the TableChange API existed.
Understand the failure class
Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.
Related errors
- Altering schema is not supported in the old alterTable API.
- this.getClass().getName() + " doesn't implement removedDelet
- Incremental scan is not supported
- Cannot update the schema of a %s table
- Altering partition keys is not supported yet.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1ee79c6f3e4a0e5a.
Report an issue: GitHub.