{"record":{"id":"f922c80da367e6fb","repo":"apache/iceberg","slug":"invalid-primary-key-s-a-primary-key-must-not-c-f922c8","errorCode":null,"errorMessage":"Invalid primary key '%s'. A primary key must not contain duplicate columns. Found: %s","messagePattern":"Invalid primary key '(.+?)'\\. A primary key must not contain duplicate columns\\. Found: (.+?)","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/FlinkSchemaUtil.java","lineNumber":349,"sourceCode":"    return new ResolvedSchema(columns, Collections.emptyList(), uniqueConstraint);\n  }\n\n  /**\n   * Copied from\n   * org.apache.flink.table.catalog.DefaultSchemaResolver#validatePrimaryKey(org.apache.flink.table.catalog.UniqueConstraint,\n   * java.util.List)\n   */\n  private static void validatePrimaryKey(UniqueConstraint primaryKey, List<Column> columns) {\n    final Map<String, Column> columnsByNameLookup =\n        columns.stream().collect(Collectors.toMap(Column::getName, Function.identity()));\n\n    final Set<String> duplicateColumns =\n        primaryKey.getColumns().stream()\n            .filter(name -> Collections.frequency(primaryKey.getColumns(), name) > 1)\n            .collect(Collectors.toSet());\n\n    if (!duplicateColumns.isEmpty()) {\n      throw new ValidationException(\n          String.format(\n              \"Invalid primary key '%s'. A primary key must not contain duplicate columns. Found: %s\",\n              primaryKey.getName(), duplicateColumns));\n    }\n\n    for (String columnName : primaryKey.getColumns()) {\n      Column column = columnsByNameLookup.get(columnName);\n      if (column == null) {\n        throw new ValidationException(\n            String.format(\n                \"Invalid primary key '%s'. Column '%s' does not exist.\",\n                primaryKey.getName(), columnName));\n      }\n\n      if (!column.isPhysical()) {\n        throw new ValidationException(\n            String.format(\n                \"Invalid primary key '%s'. Column '%s' is not a physical column.\",","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/FlinkSchemaUtil.java#L331-L367","documentation":"Validation copied from Flink's DefaultSchemaResolver: the primary key constraint lists one or more columns twice. The message names the key and the duplicate columns found by comparing the PK column list against the schema's column-name lookup — a malformed table definition, not a data issue.","triggerScenarios":"Defining PRIMARY KEY (a, a, b) or a duplicated column arising from programmatic ResolvedSchema construction, before converting to an Iceberg schema via toResolvedSchema.","commonSituations":"Generated SQL/DDL building primary keys from a collection with duplicate entries; schema evolving tooling concatenating key columns.","solutions":["Deduplicate the primary key column list before declaring the constraint","Fix the DDL so each column appears once in PRIMARY KEY clause","Ensure programmatic schema construction doesn't append the same key column twice"],"exampleFix":"// before\nPRIMARY KEY (id, id) NOT ENFORCED\n// after\nPRIMARY KEY (id) NOT ENFORCED","handlingStrategy":"validation","validationCode":"Set<String> pk = new LinkedHashSet<>(primaryKey.getColumns());\nif (pk.size() != primaryKey.getColumns().size()) {\n  throw new IllegalArgumentException(\"duplicate primary key columns\");\n}","typeGuard":null,"tryCatchPattern":"try { FlinkSchemaUtil.toResolvedSchema(schema); } catch (ValidationException e) { /* fix PK definition */ }","preventionTips":["Deduplicate PK column lists in DDL generators","Validate constraints before schema conversion","Review programmatic ResolvedSchema construction for repeated appends"],"tags":["flink","primary-key","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}