{"record":{"id":"99ec3cb609a8cd83","repo":"apache/iceberg","slug":"cannot-drop-identifier-fields-in-non-iceberg-table-99ec3c","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":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/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/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DropIdentifierFieldsExec.scala#L40-L69","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the table is Iceberg and qualify it with the Iceberg catalog name in the statement","Check `SHOW CATALOGS` / the catalog used in session config to ensure you target the Iceberg catalog","Remove identifier-field DDL from scripts for non-Iceberg tables, or migrate the table to Iceberg first"],"exampleFix":"// before\nALTER TABLE spark_catalog.default.users DROP IDENTIFIER FIELDS user_id;\n// after\nALTER TABLE iceberg_catalog.default.users DROP IDENTIFIER FIELDS user_id;","handlingStrategy":"validation","validationCode":"val table = spark.sessionState.catalogManager.currentCatalog.asTableCatalog.loadTable(ident)\nrequire(table.isInstanceOf[org.apache.iceberg.spark.source.SparkTable], s\"$ident is not an Iceberg table\")","typeGuard":"def supportsIdentifierFields(t: org.apache.spark.sql.connector.catalog.Table): Boolean = t.isInstanceOf[org.apache.iceberg.spark.source.SparkTable]","tryCatchPattern":"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) }","preventionTips":["Verify table format with DESCRIBE TABLE / DESCRIBE EXTENDED before Iceberg schema DDL","Use explicit catalog prefixes in all DDL scripts","Separate Iceberg-only DDL into scripts that only run against Iceberg catalogs"],"tags":["spark","spark-extensions","unsupported-operation","identifier-fields"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}