{"record":{"id":"d648e51144d6dccc","repo":"apache/iceberg","slug":"unsupported-table-change-setting-unique-key-const-d648e5","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.1/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.1/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java#L235-L261","documentation":"applyUniqueConstraint maps PRIMARY_KEY constraints to Iceberg identifier fields, but Iceberg has no notion of UNIQUE_KEY constraints, so UniqueConstraint.Type.UNIQUE_KEY throws UnsupportedOperationException.","triggerScenarios":"Running Flink DDL 'ALTER TABLE ... ADD UNIQUE(...) ' or a TableChange.AddUniqueConstraint with constraint type UNIQUE_KEY on an Iceberg table.","commonSituations":"Generic DDL scripts that declare unique keys for all tables, applied to Iceberg tables where only primary keys (identifier fields) exist.","solutions":["Use PRIMARY KEY instead of UNIQUE KEY in the Flink DDL for Iceberg tables","Remove the unique constraint clause; enforce uniqueness at the application/query level","Note PRIMARY KEY is mapped to Iceberg identifier fields, which do not enforce uniqueness — adjust expectations"],"exampleFix":"-- before\nALTER TABLE iceberg_table ADD UNIQUE (order_id);\n-- after\nALTER TABLE iceberg_table ADD PRIMARY KEY (order_id) NOT ENFORCED;","handlingStrategy":"validation","validationCode":"if (constraint.getType() == UniqueConstraint.Type.UNIQUE_KEY) {\n  throw new IllegalArgumentException(\"Iceberg supports only PRIMARY KEY constraints\");\n}","typeGuard":"boolean isPrimaryKeyConstraint(UniqueConstraint c) {\n  return c.getType() == UniqueConstraint.Type.PRIMARY_KEY;\n}","tryCatchPattern":"try {\n  FlinkAlterTableUtil.applySchemaChanges(update, List.of(addUnique));\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"unique key constraints\")) { /* use PRIMARY KEY instead */ }\n  throw e;\n}","preventionTips":["Declare PRIMARY KEY, not UNIQUE KEY, in Flink DDL for Iceberg tables","Remember identifier fields are not enforced uniqueness — enforce uniqueness upstream"],"tags":["flink","schema-change","constraint","unique-key","unsupported"],"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"}