apache/iceberg · error · java.lang.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

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.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:345

    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

  1. Use ALTER TABLE ... SET IDENTIFIER FIELDS col1, col2 instead of SET TBLPROPERTIES.
  2. Remove 'identifier-fields' from the property changes and issue a separate SET IDENTIFIER FIELDS statement.
  3. Add identifier fields at table creation time where supported.
  4. Check current identifier fields via DESCRIBE TABLE EXTENDED.

Example fix

// before
ALTER TABLE db.events SET TBLPROPERTIES ('identifier-fields'='id')
// after
ALTER TABLE db.events SET IDENTIFIER FIELDS id
Defensive patterns

Strategy: validation

Validate before calling

if (alterSql.toLowerCase(java.util.Locale.ROOT).contains("'identifier-fields'")) { /* rewrite to SET IDENTIFIER FIELDS */ }

Type guard

null

Try / catch

try { spark.sql(alterSql); } catch (UnsupportedOperationException e) { spark.sql("ALTER TABLE db.events SET IDENTIFIER FIELDS id"); }

Prevention

When it happens

Trigger: ALTER TABLE ... SET TBLPROPERTIES ('identifier-fields'='...') on an Iceberg table; the change reaches SparkCatalog.alterTable and hits the reserved-property check.

Common situations: 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.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/bab2e236053cc801. Report an issue: GitHub.