{"record":{"id":"d2839f4eb536ef0f","repo":"apache/iceberg","slug":"unsupported-table-change-setting-unique-key-const","errorCode":null,"errorMessage":"Unsupported table change: setting unique key constraints.","messagePattern":"Unsupported table change: setting unique key constraints\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java","lineNumber":253,"sourceCode":"    if (newPosition instanceof TableChange.First) {\n      pendingUpdate.moveFirst(modifyColumnPosition.getOldColumn().getName());\n    } else if (newPosition instanceof TableChange.After) {\n      TableChange.After after = (TableChange.After) newPosition;\n      pendingUpdate.moveAfter(modifyColumnPosition.getOldColumn().getName(), after.column());\n    } else {\n      throw new UnsupportedOperationException(\n          \"Cannot apply unknown modify-column-position change: \" + modifyColumnPosition);\n    }\n  }\n\n  private static void applyUniqueConstraint(\n      UpdateSchema pendingUpdate, UniqueConstraint constraint) {\n    switch (constraint.getType()) {\n      case PRIMARY_KEY:\n        pendingUpdate.setIdentifierFields(constraint.getColumns());\n        break;\n      case UNIQUE_KEY:\n        throw new UnsupportedOperationException(\n            \"Unsupported table change: setting unique key constraints.\");\n      default:\n        throw new UnsupportedOperationException(\n            \"Cannot apply unknown unique constraint: \" + constraint.getType().name());\n    }\n  }\n}\n","sourceCodeStart":235,"sourceCodeEnd":261,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java#L235-L261","documentation":"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.","triggerScenarios":"Running a Flink SQL/DDL ALTER TABLE that ADDs a UNIQUE constraint on an Iceberg table (constraint.getType() == UNIQUE_KEY) routed through applySchemaChanges -> applyUniqueConstraint.","commonSituations":"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.","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"],"exampleFix":"// before\nALTER TABLE iceberg_db.my_table ADD UNIQUE (email);\n// after\nALTER TABLE iceberg_db.my_table SET ('format-version'='2'); -- drop UNIQUE; enforce uniqueness upstream, or use PRIMARY KEY if identity is intended","handlingStrategy":"validation","validationCode":"for (Constraint constraint : constraints) {\n  if (constraint.getType() == ConstraintType.UNIQUE_KEY) {\n    throw new IllegalArgumentException(\n      \"Iceberg does not support UNIQUE constraints; remove UNIQUE on column(s): \" + constraint.getColumns());\n  }\n}","typeGuard":"boolean isSupportedConstraint(Constraint c) {\n  return c != null && c.getType() == ConstraintType.PRIMARY_KEY;\n}","tryCatchPattern":"try {\n  tableAdmin.applySchemaChanges(changes);\n} catch (UnsupportedOperationException e) {\n  // fallback: drop UNIQUE from DDL and continue without it\n  log.warn(\"Constraint not supported by Iceberg: {}\", e.getMessage());\n  applySchemaChanges(stripUniqueConstraints(changes));\n}","preventionTips":["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"],"tags":["flink","iceberg","ddl","unsupported-feature"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}