apache/iceberg · error
Cannot create tag to non-Iceberg table: $table
Error message
Cannot create tag to non-Iceberg table: $table
What it means
CreateOrReplaceTagExec throws this UnsupportedOperationException when a CREATE OR REPLACE TAG statement targets a non-Iceberg table. Tags are an Iceberg snapshot-reference feature that requires the underlying SparkTable to expose Iceberg's manageSnapshots API, so the plan only executes for SparkTable instances wrapping an Iceberg table. Any other table provider reaches the fallback case and fails.
Solutions
- Check the table provider with DESC TABLE EXTENDED and confirm it is iceberg.
- Fully qualify the statement with the Iceberg catalog name: CREATE OR REPLACE TAG t IN iceberg_catalog.db.tbl.
- Configure spark.sql.catalog.<name> to SparkCatalog so Iceberg identifiers resolve to SparkTable.
- Migrate the table to Iceberg if tags are required.
Example fix
-- before CREATE OR REPLACE TAG v1 AS OF VERSION 10 IN db.events; -- non-Iceberg -- after CREATE OR REPLACE TAG v1 AS OF VERSION 10 IN iceberg_catalog.db.events;
Defensive patterns
Strategy: validation
Validate before calling
assert(spark.sessionState.catalogManager.currentCatalog.name() == "iceberg_catalog", "must USE the Iceberg catalog before tag DDL")
Type guard
def supportsTags(t: org.apache.spark.sql.connector.catalog.Table): Boolean = t match { case s: org.apache.iceberg.spark.source.SparkTable => s.table().ops().current() != null; case _ => false } Try / catch
try { spark.sql("CREATE OR REPLACE TAG v1 IN cat.db.tbl") } catch { case e: UnsupportedOperationException if e.getMessage.contains("non-Iceberg table") => log.warn("tag DDL requires an Iceberg table") } Prevention
- USE the Iceberg catalog before running tag DDL
- Keep tags in scripts scoped to explicitly Iceberg-qualified table names
- Avoid mixing providers in namespaces that receive tag DDL
When it happens
Trigger: Executing CREATE OR REPLACE TAG <tag> [AS OF VERSION n] [RETAIN ...] on a table resolved from a catalog where the table is not an Iceberg SparkTable.
Common situations: Mistyping the catalog so the DDL lands on a Hive/Delta table; running tag DDL in a session where the default catalog is not the Iceberg catalog; assuming all tables in a mixed-provider namespace support tags.
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 drop tag on non-Iceberg table: $table
- Cannot add partition field to non-Iceberg table: $table
- Cannot convert predicate to SQL
- Cannot convert term to SQL
- Cannot create or replace branch on non-Iceberg table: $table
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/6f94be00ad76da82.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v3.5/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)