{"record":{"id":"8d71780792c0fbcf","repo":"apache/iceberg","slug":"cannot-specify-the-identifier-fields-because-it-8d7178","errorCode":null,"errorMessage":"Cannot specify the 'identifier-fields' because it's a reserved table property. Please use the command 'ALTER TABLE ... SET IDENTIFIER FIELDS' to specify identifier fields.","messagePattern":"Cannot specify the 'identifier-fields' because it's a reserved table property\\. Please use the command 'ALTER TABLE \\.\\.\\. SET IDENTIFIER FIELDS' to specify identifier fields\\.","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java","lineNumber":297,"sourceCode":"    SetProperty pickSnapshotId = null;\n    List<TableChange> propertyChanges = Lists.newArrayList();\n    List<TableChange> schemaChanges = Lists.newArrayList();\n\n    for (TableChange change : changes) {\n      if (change instanceof SetProperty) {\n        SetProperty set = (SetProperty) change;\n        if (TableCatalog.PROP_LOCATION.equalsIgnoreCase(set.property())) {\n          setLocation = set;\n        } else if (\"current-snapshot-id\".equalsIgnoreCase(set.property())) {\n          setSnapshotId = set;\n        } else if (\"cherry-pick-snapshot-id\".equalsIgnoreCase(set.property())) {\n          pickSnapshotId = set;\n        } else if (\"sort-order\".equalsIgnoreCase(set.property())) {\n          throw new UnsupportedOperationException(\n              \"Cannot specify the 'sort-order' because it's a reserved table \"\n                  + \"property. Please use the command 'ALTER TABLE ... WRITE ORDERED BY' to specify write sort-orders.\");\n        } else if (\"identifier-fields\".equalsIgnoreCase(set.property())) {\n          throw new UnsupportedOperationException(\n              \"Cannot specify the 'identifier-fields' because it's a reserved table property. \"\n                  + \"Please use the command 'ALTER TABLE ... SET IDENTIFIER FIELDS' to specify identifier fields.\");\n        } else {\n          propertyChanges.add(set);\n        }\n      } else if (change instanceof RemoveProperty) {\n        propertyChanges.add(change);\n      } else if (change instanceof ColumnChange) {\n        schemaChanges.add(change);\n      } else {\n        throw new UnsupportedOperationException(\"Cannot apply unknown table change: \" + change);\n      }\n    }\n\n    try {\n      org.apache.iceberg.Table table = icebergCatalog.loadTable(buildIdentifier(ident));\n      commitChanges(\n          table, setLocation, setSnapshotId, pickSnapshotId, propertyChanges, schemaChanges);","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java#L279-L315","documentation":"'identifier-fields' is a reserved Iceberg table property used to declare identifier fields, and it cannot be set via generic TBLPROPERTIES. alterTable rejects attempts with this UnsupportedOperationException and points to the dedicated ALTER TABLE ... SET IDENTIFIER FIELDS command.","triggerScenarios":"ALTER TABLE ... SET TBLPROPERTIES ('identifier-fields'='col') on an Iceberg table via SparkCatalog.alterTable.","commonSituations":"Users configuring upsert/key semantics by writing the property directly; scripts generated from documentation snippets that predate the SET IDENTIFIER FIELDS syntax; copying property-based setup from other engines.","solutions":["Use ALTER TABLE ... SET IDENTIFIER FIELDS col1, col2 to define identifier fields.","Remove the 'identifier-fields' key from the SET TBLPROPERTIES clause.","Inspect current identifier fields via DESCRIBE TABLE EXTENDED instead of rewriting the property.","Migrate automation to the dedicated identifier-fields DDL syntax."],"exampleFix":"-- before\nALTER TABLE t SET TBLPROPERTIES ('identifier-fields'='id');\n-- after\nALTER TABLE t SET IDENTIFIER FIELDS id;","handlingStrategy":"validation","validationCode":"-- Application-side precheck\nif (props.containsKey(\"identifier-fields\")) {\n  throw new IllegalArgumentException(\n      \"Use ALTER TABLE ... SET IDENTIFIER FIELDS instead of the reserved property\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  spark.sql(alterStatement);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"identifier-fields\")) {\n    // rewrite to ALTER TABLE ... SET IDENTIFIER FIELDS <cols>\n  }\n}","preventionTips":["Use SET IDENTIFIER FIELDS DDL rather than the raw property","Scrub reserved keys from any property-setting tooling","Document identifier-fields as managed in internal runbooks","Verify current identifier fields with DESCRIBE TABLE EXTENDED before changes"],"tags":["spark","ddl","reserved-property","identifier-fields"],"backgroundTag":"invalid-config-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"}