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

This UnsupportedOperationException is thrown by Spark's DROP IDENTIFIER FIELDS execution when the target table is not an Iceberg table. Identifier fields are part of the Iceberg table schema spec, so only Iceberg tables support setting/dropping them; the non-Iceberg match arm throws.

Solutions

  1. Verify the table is Iceberg-managed
  2. Fully qualify the table with the Iceberg catalog name
  3. Fix the spark.sql.catalog registration so the table resolves to Iceberg
  4. If identifiers aren't needed, skip the operation on non-Iceberg tables

Example fix

// before
ALTER TABLE plain_table DROP IDENTIFIER FIELDS id;
// after
ALTER TABLE iceberg_catalog.db.plain_table DROP IDENTIFIER FIELDS id;
Defensive patterns

Strategy: validation

Validate before calling

val icebergTable = Spark3Util.loadIcebergTable(spark, fullTableName)
require(icebergTable != null, s"$fullTableName is not an Iceberg table")

Type guard

def isIcebergTable(spark: SparkSession, name: String): Boolean =
  scala.util.Try(Spark3Util.loadIcebergTable(spark, name)).map(_ != null).getOrElse(false)

Prevention

When it happens

Trigger: Running 'ALTER TABLE ... DROP IDENTIFIER FIELDS ...' against a table that resolves to a non-Iceberg Spark table.

Common situations: Using Iceberg-specific schema DDL on Delta/Parquet/Hive tables; catalog alias resolving to a non-Iceberg provider.

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

Appendix: source

Thrown at spark/v4.2/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)