apache/iceberg · error · 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
Apache Iceberg's FlinkCatalog does not support schema changes through Flink's legacy `alterTable(ObjectPath, CatalogTable, boolean)` API. The method compares the unresolved schema of the existing table with the requested one, and any difference throws UnsupportedOperationException. Schema evolution must go through the newer alterTable API that accepts a list of TableChange objects.
Solutions
- Use the TableChange-based alterTable API: `alterTable(tablePath, List.of(SchemaEvolutionUtil.addSchemaChange(...)), false)` or Flink's `ALTER TABLE ... ADD COLUMN` which maps to it.
- Verify that the new CatalogTable differs from the old one only in options/partition-independent properties if you must use the legacy API.
- Rewrite the migration code to issue explicit TableChange.addColumn/dropColumn/renameColumn updates.
Example fix
// before
catalog.alterTable(tablePath, modifiedCatalogTable, false);
// after
catalog.alterTable(tablePath,
List.of(Change.addColumn("new_col", Types.LongType.get())),
false); Defensive patterns
Strategy: try-catch
Validate before calling
// compare schemas before calling legacy alterTable
if (!Objects.equals(oldCt.getUnresolvedSchema(), newCt.getUnresolvedSchema())) {
// switch to TableChange-based alterTable instead
} Type guard
boolean legacyApiSafe(CatalogTable a, CatalogTable b) {
return Objects.equals(a.getUnresolvedSchema(), b.getUnresolvedSchema());
} Try / catch
try {
catalog.alterTable(tablePath, ct, false);
} catch (UnsupportedOperationException e) {
// fall back to TableChange-based alterTable for schema evolution
} Prevention
- Prefer the TableChange-based alterTable API for any schema-affecting change
- Diff unresolved schemas before calling the legacy API
- Keep DDL migrations expressed as explicit TableChange lists
When it happens
Trigger: Calling catalog.alterTable(tablePath, newCatalogTable, false) where newCatalogTable.getUnresolvedSchema() differs from the existing table's schema (e.g. added, dropped, renamed, or retyped columns).
Common situations: Using an old Flink SQL `ALTER TABLE ... ADD/DROP COLUMN` path or a framework that still routes schema DDL through the legacy Catalog API instead of the TableChange-based API.
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 modify-column change
- Cannot apply unknown modify-column-position change
- Cannot apply unknown table change:
- Cannot apply unknown table change:
- Cannot apply unknown table change
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8f59268b935ab801.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.2/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)