apache/iceberg · error · UnsupportedOperationException
Cannot create tag to non-Iceberg table: $table
Error message
Cannot create tag to non-Iceberg table: $table
What it means
CreateOrReplaceTagExec commits tag creation via manageSnapshot only for Iceberg tables. When the resolved table is not an Iceberg table, the catch-all case throws this UnsupportedOperationException, since tags (named snapshot references) are an Iceberg-only feature.
Solutions
- Prefix the table with its Iceberg catalog name: `ALTER TABLE iceberg_catalog.db.t CREATE TAG tag1 ...`.
- Check spark.sql.catalog.* configuration to ensure the intended catalog is Iceberg's SparkCatalog/SparkSessionCatalog.
- Confirm the table is Iceberg-format; if not, migrate or skip it in batch scripts.
- Guard batch scripts by checking the table format (via DESCRIBE TABLE / catalog API) before issuing tag DDL.
Example fix
-- before ALTER TABLE spark_catalog.db.t CREATE TAG v1 -- after ALTER TABLE iceberg_catalog.db.t CREATE TAG v1
Defensive patterns
Strategy: type-guard
Validate before calling
// Scala: guard tag DDL behind an Iceberg-catalog check
val ok = spark.conf.get(s"spark.sql.catalog.iceberg_catalog", "")
.contains("org.apache.iceberg.spark.SparkCatalog") Type guard
// Scala
table match {
case _: org.apache.iceberg.spark.SparkTable => true
case _ => false // cannot tag non-Iceberg tables
} Try / catch
// Scala
try {
spark.sql(s"ALTER TABLE $ident CREATE TAG $tag")
} catch {
case _: UnsupportedOperationException => log.warn(s"Skipping tag on $ident: not an Iceberg table")
} Prevention
- Prefix table identifiers with the Iceberg catalog name.
- In batch tagging scripts, check the table's format first and skip non-Iceberg entries.
- Keep one Iceberg catalog configured and consistently named across jobs.
When it happens
Trigger: Running `ALTER TABLE ... CREATE TAG ...` (or CREATE OR REPLACE TAG) against a table backed by a non-Iceberg catalog or format.
Common situations: Forgetting the Iceberg catalog prefix so the table resolves via spark_catalog, targeting Delta/Parquet tables, or scripts that iterate mixed-format tables and attempt tagging on all of them.
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
- Cannot add partition field to non-Iceberg table: $table
- Cannot create or replace branch on non-Iceberg table: $table
- Cannot create tag to non-Iceberg table: $table
- Cannot drop tag on non-Iceberg table: $table
- Altering a view is not supported by catalog:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8bba60070acc45e4.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/CreateOrReplaceTagExec.scala:77
manageSnapshot.createTag(tag, snapshotId)
} else if (replace) {
manageSnapshot.replaceTag(tag, snapshotId)
} else {
if (refExists && ifNotExists) {
return Nil
}
manageSnapshot.createTag(tag, snapshotId)
}
if (tagOptions.snapshotRefRetain.nonEmpty) {
manageSnapshot.setMaxRefAgeMs(tag, tagOptions.snapshotRefRetain.get)
}
manageSnapshot.commit()
case table =>
throw new UnsupportedOperationException(s"Cannot create tag to non-Iceberg table: $table")
}
Nil
}
override def simpleString(maxFields: Int): String = {
s"Create tag: $tag for table: ${ident.quoted}"
}
}
View on GitHub (pinned to 86d9c8fc54)