apache/iceberg · error · UnsupportedOperationException
Cannot specify the 'identifier-fields' because it's a reserv
Error message
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.
What it means
Validation in SparkCatalog.alterTable: a SetProperty change targeted the reserved 'identifier-fields' table property. Identifier fields cannot be set as properties; they must be managed with ALTER TABLE ... SET IDENTIFIER FIELDS, so the property change is rejected during change classification (before any update is applied).
Source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:346
SetProperty pickSnapshotId = null;
List<TableChange> propertyChanges = Lists.newArrayList();
List<TableChange> schemaChanges = Lists.newArrayList();
for (TableChange change : changes) {
if (change instanceof SetProperty) {
SetProperty set = (SetProperty) change;
if (TableCatalog.PROP_LOCATION.equalsIgnoreCase(set.property())) {
setLocation = set;
} else if ("current-snapshot-id".equalsIgnoreCase(set.property())) {
setSnapshotId = set;
} else if ("cherry-pick-snapshot-id".equalsIgnoreCase(set.property())) {
pickSnapshotId = set;
} else if ("sort-order".equalsIgnoreCase(set.property())) {
throw new UnsupportedOperationException(
"Cannot specify the 'sort-order' because it's a reserved table "
+ "property. Please use the command 'ALTER TABLE ... WRITE ORDERED BY' to specify write sort-orders.");
} else if ("identifier-fields".equalsIgnoreCase(set.property())) {
throw new UnsupportedOperationException(
"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.");
} else {
propertyChanges.add(set);
}
} else if (change instanceof RemoveProperty) {
propertyChanges.add(change);
} else if (change instanceof ColumnChange) {
schemaChanges.add(change);
} else {
throw new UnsupportedOperationException("Cannot apply unknown table change: " + change);
}
}
try {
org.apache.iceberg.Table table = icebergCatalog.loadTable(buildIdentifier(ident));
commitChanges(
table, setLocation, setSnapshotId, pickSnapshotId, propertyChanges, schemaChanges);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use ALTER TABLE ... SET IDENTIFIER FIELDS col1, col2 instead of setting the property.
- Exclude 'identifier-fields' from any generic property re-application script.
- If identifier fields need to change, use the dedicated clause (or clear them first) per Iceberg's identifier-field semantics.
- Audit generated DDL for reserved property names before executing.
Example fix
// before
spark.sql("ALTER TABLE prod.db.users SET TBLPROPERTIES ('identifier-fields'='user_id')");
// after
spark.sql("ALTER TABLE prod.db.users SET IDENTIFIER FIELDS user_id"); Defensive patterns
Strategy: validation
Validate before calling
if ("identifier-fields".equalsIgnoreCase(propKey)) {
throw new IllegalArgumentException("Use SET IDENTIFIER FIELDS instead of setting the property");
} Try / catch
try {
spark.sql(alterSql);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("'identifier-fields'")) {
throw new IllegalArgumentException("Use ALTER TABLE ... SET IDENTIFIER FIELDS", e);
}
throw e;
} Prevention
- Use ALTER TABLE ... SET IDENTIFIER FIELDS for identifier fields.
- Filter 'identifier-fields' out of property-sync/replay scripts.
- Treat it like 'sort-order' as managed metadata, not a user property.
- Validate DDL generators against the reserved-property list.
When it happens
Trigger: ALTER TABLE ... SET TBLPROPERTIES ('identifier-fields' = '...') or TableChange.setProperty("identifier-fields", ...) sent through alterTable.
Common situations: Blind property-sync scripts that re-apply every property from SHOW TBLPROPERTIES output; migrations between environments that include reserved properties; manual edits of table metadata copied as SQL.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot specify the 'sort-order' because it's a reserved tabl
- Cannot specify the 'sort-order' because it's a reserved tabl
- Cannot specify the 'identifier-fields' because it's a reserv
- Cannot apply unknown table change:
- Cannot apply unknown table change: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/a44b10fb0f450083.
Report an issue: GitHub.