{"record":{"id":"a7712f928e67de78","repo":"apache/iceberg","slug":"cannot-apply-unknown-unique-constraint-constrain","errorCode":null,"errorMessage":"Cannot apply unknown unique constraint: {constraint.getType().name()}","messagePattern":"Cannot apply unknown unique constraint: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java","lineNumber":256,"sourceCode":"      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":238,"sourceCodeEnd":261,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java#L238-L261","documentation":"When applying Flink schema changes to an Iceberg table, the unique-constraint applicator only handles PRIMARY_KEY constraints; UNIQUE_KEY or any other constraint type is rejected. The default branch catches constraint types not explicitly handled, meaning the Flink-to-Iceberg mapping does not support this constraint kind. This is a deliberate guard: Iceberg tables do not model UNIQUE constraints like relational engines do.","triggerScenarios":"Calling applySchemaChanges/applyUniqueConstraint with a Flink table change whose UniqueConstraint.getType() is UNIQUE_KEY or any non-PRIMARY_KEY type, e.g. a CREATE TABLE or ALTER TABLE with a UNIQUE constraint in Flink SQL against an Iceberg catalog.","commonSituations":"Migrating Flink SQL DDL written for JDBC/Hive tables (which support UNIQUE keys) to an Iceberg catalog; schema-sync tools that copy full constraint sets; ORMs generating UNIQUE KEY definitions.","solutions":["Remove the UNIQUE constraint from the Flink DDL; Iceberg does not enforce unique keys","Keep only PRIMARY KEY constraints, which are mapped to Iceberg identifier fields","Enforce uniqueness at the engine/job level (e.g. upsert logic) instead of the catalog","If PRIMARY_KEY support is what you need, verify constraint.getType() is PRIMARY_KEY before calling"],"exampleFix":"// before\nCREATE TABLE t (id INT, name STRING, UNIQUE (name)) WITH ('connector'='iceberg');\n// after\nCREATE TABLE t (id INT, name STRING, PRIMARY KEY (id) NOT ENFORCED) WITH ('connector'='iceberg');","handlingStrategy":"validation","validationCode":"if (constraint.getType() != UniqueConstraint.Type.PRIMARY_KEY) {\n  throw new IllegalArgumentException(\n    \"Iceberg supports only PRIMARY_KEY constraints, got: \" + constraint.getType());\n}\napplySchemaChange(update);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use PRIMARY KEY (NOT ENFORCED) in Flink DDL targeting Iceberg tables","Avoid copying UNIQUE constraints when migrating schemas from JDBC/Hive to Iceberg","Keep a schema-mapping layer that drops unsupported constraint types explicitly"],"tags":["flink","unsupported-operation","schema"],"backgroundTag":"unsupported-enum-value","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"}