apache/iceberg · error

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 UnsupportedOperationException when a DROP IDENTIFIER FIELDS statement targets a non-Iceberg table. Identifier fields are an Iceberg schema feature managed via updateSchema().setIdentifierFields, available only on SparkTable instances wrapping Iceberg tables. Other providers hit the fallback case and throw.

Source

Thrown at spark/v3.5/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)

Solutions

  1. Verify the table provider is iceberg with DESC TABLE EXTENDED.
  2. Qualify the statement with the Iceberg catalog: ALTER TABLE iceberg_catalog.db.tbl DROP IDENTIFIER FIELDS id.
  3. Register the catalog with SparkCatalog so identifiers resolve to Iceberg SparkTables.
  4. Drop identifier fields via the Iceberg API on the correct table instead.

Example fix

-- before
ALTER TABLE db.events DROP IDENTIFIER FIELDS id; -- non-Iceberg
-- after
ALTER TABLE iceberg_catalog.db.events DROP IDENTIFIER FIELDS id;
Defensive patterns

Strategy: validation

Validate before calling

val isIceberg = spark.conf.getOption(s"spark.sql.catalog.$catalogName").exists(_.contains("SparkCatalog"))

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("ALTER TABLE cat.db.tbl DROP IDENTIFIER FIELDS id") } catch { case e: UnsupportedOperationException if e.getMessage.contains("non-Iceberg") => log.warn("identifier fields require Iceberg") }

Prevention

When it happens

Trigger: Executing ALTER TABLE ... DROP IDENTIFIER FIELDS on a table whose resolved SparkTable is not an Iceberg table, so the `case iceberg: SparkTable` match fails.

Common situations: Running identifier-field DDL against Hive/Delta tables; wrong default catalog in a multi-catalog session; copying Iceberg DDL onto tables that were migrated away from 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/ab3098a287180d7e. Report an issue: GitHub.