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
'identifier-fields' is a reserved Iceberg table property that can only be changed through the dedicated SQL syntax ALTER TABLE ... SET IDENTIFIER FIELDS. SparkCatalog.alterTable detects a SetProperty change on this property and throws UnsupportedOperationException to prevent corrupting identifier metadata.
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:325
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 id (comma-separated for multiple fields) instead of setting the property
- Filter reserved keys out of property-copy automation before calling SET TBLPROPERTIES
- Use the Iceberg API Table.updateSchema().setIdentifierFields(...) when not using SQL
Example fix
// before
ALTER TABLE t SET TBLPROPERTIES ('identifier-fields'='id');
// after
ALTER TABLE t SET IDENTIFIER FIELDS id; Defensive patterns
Strategy: validation
Validate before calling
if ("identifier-fields".equalsIgnoreCase(key)) { throw new IllegalArgumentException("Use ALTER TABLE ... SET IDENTIFIER FIELDS"); } Type guard
boolean isReservedIcebergProperty(String key) { return Set.of("sort-order","identifier-fields").contains(key.toLowerCase(Locale.ROOT)); } Try / catch
try { spark.sql(alterStmt); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("identifier-fields")) { spark.sql("ALTER TABLE t SET IDENTIFIER FIELDS " + fields); } } Prevention
- Strip reserved properties before programmatic SET TBLPROPERTIES
- Document identifier-fields as API-managed, not property-managed
- Use UpdateSchema.setIdentifierFields for programmatic changes
When it happens
Trigger: Running ALTER TABLE ... SET TBLPROPERTIES ('identifier-fields'='id') or otherwise submitting an UpdateTable change with property 'identifier-fields' through SparkCatalog.alterTable.
Common situations: Scripts replaying a table's full property map (including reserved keys) onto a new table; users manually trying to set identifier fields without knowing the dedicated SQL command; version migrations where identifier fields were configured differently.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot specify the 'identifier-fields' because it's a reserv
- Cannot specify the 'identifier-fields' because it's a reserv
- 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
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/11812ebb7d408229.
Report an issue: GitHub.