{"record":{"id":"fd939ccd9f2eb71e","repo":"apache/iceberg","slug":"cannot-set-identifier-fields-in-non-iceberg-table","errorCode":null,"errorMessage":"Cannot set identifier fields in non-Iceberg table: $table","messagePattern":"Cannot set 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/SetIdentifierFieldsExec.scala","lineNumber":42,"sourceCode":"import org.apache.spark.sql.connector.catalog.Identifier\nimport org.apache.spark.sql.connector.catalog.TableCatalog\nimport scala.jdk.CollectionConverters._\n\ncase class SetIdentifierFieldsExec(catalog: TableCatalog, ident: Identifier, fields: Seq[String])\n    extends LeafV2CommandExec {\n  import org.apache.spark.sql.connector.catalog.CatalogV2Implicits._\n\n  override lazy val output: Seq[Attribute] = Nil\n\n  override protected def run(): Seq[InternalRow] = {\n    catalog.loadTable(ident) match {\n      case iceberg: SparkTable =>\n        iceberg.table\n          .updateSchema()\n          .setIdentifierFields(fields.asJava)\n          .commit();\n      case table =>\n        throw new UnsupportedOperationException(\n          s\"Cannot set identifier fields in non-Iceberg table: $table\")\n    }\n\n    Nil\n  }\n\n  override def simpleString(maxFields: Int): String = {\n    s\"SetIdentifierFields ${catalog.name}.${ident.quoted} (${fields.quoted})\";\n  }\n}\n","sourceCodeStart":24,"sourceCodeEnd":53,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/SetIdentifierFieldsExec.scala#L24-L53","documentation":"SetIdentifierFieldsExec throws this UnsupportedOperationException when a SET IDENTIFIER FIELDS statement targets a non-Iceberg table. Setting identifier fields requires Iceberg's updateSchema().setIdentifierFields() API, exposed only by SparkTable instances wrapping Iceberg tables. Any other resolved table reaches the fallback throwing case.","triggerScenarios":"Running ALTER TABLE ... SET IDENTIFIER FIELDS <cols> where the resolved table does not match `iceberg: SparkTable`, so the pattern match fails.","commonSituations":"Identifier-field DDL executed on Hive/Delta tables; wrong catalog binding so the command resolves through a non-Iceberg provider; teams rolling out row-level-dedupe features onto tables not yet migrated to Iceberg.","solutions":["Verify the provider with DESC TABLE EXTENDED and confirm iceberg.","Qualify the statement with the Iceberg catalog: ALTER TABLE iceberg_catalog.db.tbl SET IDENTIFIER FIELDS id.","Register the catalog as org.apache.iceberg.spark.SparkCatalog so identifiers produce SparkTables.","Migrate the table to Iceberg if identifier fields are needed for row-level operations."],"exampleFix":"-- before\nALTER TABLE db.events SET IDENTIFIER FIELDS event_id; -- non-Iceberg\n-- after\nALTER TABLE iceberg_catalog.db.events SET IDENTIFIER FIELDS event_id;","handlingStrategy":"validation","validationCode":"val provider = spark.sql(\"DESC TABLE EXTENDED cat.db.tbl\").where(\"col_name = 'Provider'\").first().getString(1)\nrequire(provider == \"iceberg\", \"SET IDENTIFIER FIELDS requires Iceberg\")","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 SET IDENTIFIER FIELDS event_id\") } catch { case e: UnsupportedOperationException if e.getMessage.contains(\"non-Iceberg\") => log.warn(\"identifier fields require an Iceberg table\") }","preventionTips":["Run identifier-field DDL only against Iceberg-qualified table names","Check Provider in DESC TABLE EXTENDED before schema DDL","Register catalogs with org.apache.iceberg.spark.SparkCatalog so DDL resolves to Iceberg tables"],"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"}