{"record":{"id":"ab3098a287180d7e","repo":"apache/iceberg","slug":"cannot-drop-identifier-fields-in-non-iceberg-table","errorCode":null,"errorMessage":"Cannot drop identifier fields in non-Iceberg table: $table","messagePattern":"Cannot drop identifier fields in non-Iceberg table: \\$table","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DropIdentifierFieldsExec.scala","lineNumber":58,"sourceCode":"\n        for (name <- fields) {\n          Preconditions.checkArgument(\n            schema.findField(name) != null,\n            \"Cannot complete drop identifier fields operation: field %s not found\",\n            name)\n          Preconditions.checkArgument(\n            identifierFieldNames.contains(name),\n            \"Cannot complete drop identifier fields operation: %s is not an identifier field\",\n            name)\n          identifierFieldNames.remove(name)\n        }\n\n        iceberg.table\n          .updateSchema()\n          .setIdentifierFields(identifierFieldNames)\n          .commit();\n      case table =>\n        throw new UnsupportedOperationException(\n          s\"Cannot drop identifier fields in non-Iceberg table: $table\")\n    }\n\n    Nil\n  }\n\n  override def simpleString(maxFields: Int): String = {\n    s\"DropIdentifierFields ${catalog.name}.${ident.quoted} (${fields.quoted})\";\n  }\n}\n","sourceCodeStart":40,"sourceCodeEnd":69,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DropIdentifierFieldsExec.scala#L40-L69","documentation":"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.","triggerScenarios":"Executing ALTER TABLE ... DROP IDENTIFIER FIELDS on a table whose resolved SparkTable is not an Iceberg table, so the `case iceberg: SparkTable` match fails.","commonSituations":"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.","solutions":["Verify the table provider is iceberg with DESC TABLE EXTENDED.","Qualify the statement with the Iceberg catalog: ALTER TABLE iceberg_catalog.db.tbl DROP IDENTIFIER FIELDS id.","Register the catalog with SparkCatalog so identifiers resolve to Iceberg SparkTables.","Drop identifier fields via the Iceberg API on the correct table instead."],"exampleFix":"-- before\nALTER TABLE db.events DROP IDENTIFIER FIELDS id; -- non-Iceberg\n-- after\nALTER TABLE iceberg_catalog.db.events DROP IDENTIFIER FIELDS id;","handlingStrategy":"validation","validationCode":"val isIceberg = spark.conf.getOption(s\"spark.sql.catalog.$catalogName\").exists(_.contains(\"SparkCatalog\"))","typeGuard":"def supportsIdentifierFields(t: org.apache.spark.sql.connector.catalog.Table): Boolean = t.isInstanceOf[org.apache.iceberg.spark.source.SparkTable]","tryCatchPattern":"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\") }","preventionTips":["Only run schema identifier DDL on Iceberg-qualified names","Verify catalog registration before identifier-field operations","Keep Iceberg-only DDL in scripts that assert provider first"],"tags":["spark","iceberg","unsupported-operation","schema"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}