apache/iceberg · error · UnsupportedOperationException
Unsupported table change: setting unique key constraints.
Error message
Unsupported table change: setting unique key constraints.
What it means
Flink's alter-table path in FlinkAlterTableUtil translates Flink schema-change operations into Iceberg UpdateSchema calls. Iceberg has no notion of UNIQUE key constraints — only primary keys (identifier fields) are supported — so any attempt to apply a UNIQUE_KEY constraint is rejected up front with UnsupportedOperationException. This is an intentional capability gap, not a transient failure.
Source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java:253
if (newPosition instanceof TableChange.First) {
pendingUpdate.moveFirst(modifyColumnPosition.getOldColumn().getName());
} else if (newPosition instanceof TableChange.After) {
TableChange.After after = (TableChange.After) newPosition;
pendingUpdate.moveAfter(modifyColumnPosition.getOldColumn().getName(), after.column());
} else {
throw new UnsupportedOperationException(
"Cannot apply unknown modify-column-position change: " + modifyColumnPosition);
}
}
private static void applyUniqueConstraint(
UpdateSchema pendingUpdate, UniqueConstraint constraint) {
switch (constraint.getType()) {
case PRIMARY_KEY:
pendingUpdate.setIdentifierFields(constraint.getColumns());
break;
case UNIQUE_KEY:
throw new UnsupportedOperationException(
"Unsupported table change: setting unique key constraints.");
default:
throw new UnsupportedOperationException(
"Cannot apply unknown unique constraint: " + constraint.getType().name());
}
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Remove the UNIQUE constraint from the DDL and enforce uniqueness at the application/upstream level
- Use PRIMARY KEY (...) instead if the columns can serve as row identity — Iceberg maps it to identifier fields via setIdentifierFields
- Verify the target table actually supports the change: confirm the connector is Iceberg and consult supported Flink DDL operations for the module version
Example fix
// before
ALTER TABLE iceberg_db.my_table ADD UNIQUE (email);
// after
ALTER TABLE iceberg_db.my_table SET ('format-version'='2'); -- drop UNIQUE; enforce uniqueness upstream, or use PRIMARY KEY if identity is intended Defensive patterns
Strategy: validation
Validate before calling
for (Constraint constraint : constraints) {
if (constraint.getType() == ConstraintType.UNIQUE_KEY) {
throw new IllegalArgumentException(
"Iceberg does not support UNIQUE constraints; remove UNIQUE on column(s): " + constraint.getColumns());
}
} Type guard
boolean isSupportedConstraint(Constraint c) {
return c != null && c.getType() == ConstraintType.PRIMARY_KEY;
} Try / catch
try {
tableAdmin.applySchemaChanges(changes);
} catch (UnsupportedOperationException e) {
// fallback: drop UNIQUE from DDL and continue without it
log.warn("Constraint not supported by Iceberg: {}", e.getMessage());
applySchemaChanges(stripUniqueConstraints(changes));
} Prevention
- Never emit UNIQUE constraints in DDL targeting Iceberg tables
- Use PRIMARY KEY only, and only on columns suitable as identifier fields
- Review ORM/schema-migration tooling to skip UNIQUE clauses for Iceberg connectors
- Consult the iceberg-flink module docs for supported ALTER operations before generating DDL
When it happens
Trigger: Running a Flink SQL/DDL ALTER TABLE that ADDs a UNIQUE constraint on an Iceberg table (constraint.getType() == UNIQUE_KEY) routed through applySchemaChanges -> applyUniqueConstraint.
Common situations: Migrating DDL written for other engines (MySQL/Postgres/Spark dialects) that permit UNIQUE keys; ORM/schema-sync tools generating UNIQUE constraints; users assuming parity between Iceberg primary keys and unique keys.
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
- Unsupported table change: setting unique key constraints.
- Cannot create the table with 'connector'='iceberg' table pro
- Altering partition keys is not supported yet.
- Failed to list partitions of table %s
- Unsupported YearMonthIntervalType.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/d2839f4eb536ef0f.
Report an issue: GitHub.