apache/iceberg · error · UnsupportedOperationException

Cannot drop identifier fields in non-Iceberg table: $table

Error message

Cannot drop identifier fields in non-Iceberg table: $table

What it means

DropIdentifierFieldsExec throws this when ALTER TABLE ... DROP IDENTIFIER FIELDS is executed against a table that is not an Iceberg SparkTable. Identifier fields are an Iceberg schema concept (upsert/delete keys), so only Iceberg's UpdateSchema API supports removing them. The executor pattern-matches on SparkTable and throws UnsupportedOperationException for any other V2 table.

Solutions

  1. Confirm the table is Iceberg and qualify it with the Iceberg catalog name in the statement
  2. Check `SHOW CATALOGS` / the catalog used in session config to ensure you target the Iceberg catalog
  3. Remove identifier-field DDL from scripts for non-Iceberg tables, or migrate the table to Iceberg first

Example fix

// before
ALTER TABLE spark_catalog.default.users DROP IDENTIFIER FIELDS user_id;
// after
ALTER TABLE iceberg_catalog.default.users DROP IDENTIFIER FIELDS user_id;
Defensive patterns

Strategy: validation

Validate before calling

val table = spark.sessionState.catalogManager.currentCatalog.asTableCatalog.loadTable(ident)
require(table.isInstanceOf[org.apache.iceberg.spark.source.SparkTable], s"$ident is not an Iceberg table")

Type guard

def supportsIdentifierFields(t: org.apache.spark.sql.connector.catalog.Table): Boolean = t.isInstanceOf[org.apache.iceberg.spark.source.SparkTable]

Try / catch

try { spark.sql(s"ALTER TABLE $ident DROP IDENTIFIER FIELDS id") } catch { case e: UnsupportedOperationException if e.getMessage.contains("non-Iceberg") => throw new IllegalStateException(s"Identifier fields require an Iceberg table: $ident", e) }

Prevention

When it happens

Trigger: Executing `ALTER TABLE ... DROP IDENTIFIER FIELDS id` where the resolved table is from a non-Iceberg catalog (Delta, JDBC, custom V2), failing the `iceberg: SparkTable` match.

Common situations: Wrong catalog prefix in SQL; copy-pasted Iceberg DDL scripts run against tables migrated off Iceberg; environments where multiple catalogs are registered and the default is not Iceberg.

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/99ec3cb609a8cd83. Report an issue: GitHub.

Appendix: source

Thrown at spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DropIdentifierFieldsExec.scala:58

        for (name <- fields) {
          Preconditions.checkArgument(
            schema.findField(name) != null,
            "Cannot complete drop identifier fields operation: field %s not found",
            name)
          Preconditions.checkArgument(
            identifierFieldNames.contains(name),
            "Cannot complete drop identifier fields operation: %s is not an identifier field",
            name)
          identifierFieldNames.remove(name)
        }

        iceberg.table
          .updateSchema()
          .setIdentifierFields(identifierFieldNames)
          .commit();
      case table =>
        throw new UnsupportedOperationException(
          s"Cannot drop identifier fields in non-Iceberg table: $table")
    }

    Nil
  }

  override def simpleString(maxFields: Int): String = {
    s"DropIdentifierFields ${catalog.name}.${ident.quoted} (${fields.quoted})";
  }
}

View on GitHub (pinned to 86d9c8fc54)