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

  1. Check the table provider with DESC TABLE EXTENDED and confirm it is iceberg.
  2. Fully qualify the statement with the Iceberg catalog name: CREATE OR REPLACE TAG t IN iceberg_catalog.db.tbl.
  3. Configure spark.sql.catalog.<name> to SparkCatalog so Iceberg identifiers resolve to SparkTable.
  4. 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

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


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)