{"record":{"id":"342f3afd8cbe37b8","repo":"apache/iceberg","slug":"unsupported-table-change-setting-unique-key-const-342f3a","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/v2.2/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/v2.2/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java#L235-L261","documentation":"Iceberg has no native UNIQUE KEY constraint concept — only identifier fields (primary key). When applyUniqueConstraint receives a UniqueConstraint of type UNIQUE_KEY it throws UnsupportedOperationException because UpdateSchema cannot represent it.","triggerScenarios":"ALTER TABLE ... ADD UNIQUE(...) or a Flink connector config declaring unique keys on an Iceberg table routed to applySchemaChanges → applyUniqueConstraint.","commonSituations":"Porting warehouse DDL that uses UNIQUE constraints (e.g. from MySQL) to Iceberg; Flink SQL CREATE TABLE with UNIQUE declared; data quality tooling asserting uniqueness via constraint DDL.","solutions":["Remove UNIQUE declarations from the DDL; enforce uniqueness upstream or in pipeline logic instead","Express the closest intent as identifier fields (setIdentifierFields) if the columns can act as a primary key","Catch UnsupportedOperationException and document to users that Iceberg/Flink path supports only PRIMARY_KEY constraints"],"exampleFix":"// before\nALTER TABLE t ADD UNIQUE (email);\n// after\n-- enforce uniqueness in pipeline, or:\ntable.updateSchema().setIdentifierFields(\"email\").commit();","handlingStrategy":"validation","validationCode":"boolean hasUniqueKey = changes.stream()\n    .filter(c -> c instanceof TableChange.AddUniqueConstraint || c instanceof TableChange.ModifyUniqueConstraint)\n    .map(c -> c instanceof TableChange.AddUniqueConstraint\n        ? ((TableChange.AddUniqueConstraint) c).getConstraint()\n        : ((TableChange.ModifyUniqueConstraint) c).getNewConstraint())\n    .anyMatch(u -> u.getType() == ConstraintType.UNIQUE_KEY);\nif (hasUniqueKey) throw new IllegalArgumentException(\"Iceberg supports only PRIMARY_KEY constraints\");","typeGuard":"static boolean isPrimaryKeyConstraint(UniqueConstraint u) { return u.getType() == ConstraintType.PRIMARY_KEY; }","tryCatchPattern":"try { FlinkAlterTableUtil.applySchemaChanges(update, changes); }\ncatch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"unique key constraints\")) { /* strip UNIQUE DDL and warn user */ }\n  throw e;\n}","preventionTips":["Do not declare UNIQUE keys in Iceberg DDL via Flink","Enforce uniqueness in pipeline/application logic","Use identifier fields only where a true primary key exists"],"tags":["flink","iceberg","unique-constraint","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"}