{"record":{"id":"bab2e236053cc801","repo":"apache/iceberg","slug":"cannot-specify-the-identifier-fields-because-it","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/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java","lineNumber":345,"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":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java#L327-L363","documentation":"The 'identifier-fields' property is reserved for Iceberg's identifier field metadata and cannot be set directly via SET TBLPROPERTIES. SparkCatalog.alterTable intercepts the key at line 345 and throws UnsupportedOperationException directing the user to Spark's identifier-field syntax.","triggerScenarios":"ALTER TABLE ... SET TBLPROPERTIES ('identifier-fields'='...') on an Iceberg table; the change reaches SparkCatalog.alterTable and hits the reserved-property check.","commonSituations":"Porting SQL from engines where identifiers are set via properties; hand-written DDL copied from documentation of other catalogs; code generators emitting identifier-fields as a property.","solutions":["Use ALTER TABLE ... SET IDENTIFIER FIELDS col1, col2 instead of SET TBLPROPERTIES.","Remove 'identifier-fields' from the property changes and issue a separate SET IDENTIFIER FIELDS statement.","Add identifier fields at table creation time where supported.","Check current identifier fields via DESCRIBE TABLE EXTENDED."],"exampleFix":"// before\nALTER TABLE db.events SET TBLPROPERTIES ('identifier-fields'='id')\n// after\nALTER TABLE db.events SET IDENTIFIER FIELDS id","handlingStrategy":"validation","validationCode":"if (alterSql.toLowerCase(java.util.Locale.ROOT).contains(\"'identifier-fields'\")) { /* rewrite to SET IDENTIFIER FIELDS */ }","typeGuard":"null","tryCatchPattern":"try { spark.sql(alterSql); } catch (UnsupportedOperationException e) { spark.sql(\"ALTER TABLE db.events SET IDENTIFIER FIELDS id\"); }","preventionTips":["Use SET IDENTIFIER FIELDS syntax.","Keep reserved-property lists in shared DDL linting.","Add identifier fields at create time when possible."],"tags":["spark","alter-table","reserved-property","identifier-fields"],"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"}