apache/iceberg · error

Cannot drop tag on non-Iceberg table: $table

Error message

Cannot drop tag on non-Iceberg table: $table

What it means

DropTagExec throws this UnsupportedOperationException when a DROP TAG statement targets a non-Iceberg table. Removing a tag needs Iceberg's manageSnapshots().removeTag() API, only available on SparkTable instances wrapping Iceberg tables. Other providers reach the fallback throwing case.

Solutions

  1. Confirm the table is Iceberg via DESC TABLE EXTENDED.
  2. Fully qualify the statement: DROP TAG v1 IN iceberg_catalog.db.tbl.
  3. Ensure the catalog is registered as org.apache.iceberg.spark.SparkCatalog.
  4. Skip non-Iceberg tables in batch cleanup scripts (filter by provider).

Example fix

-- before
DROP TAG v1 IN db.events; -- non-Iceberg
-- after
DROP TAG v1 IN iceberg_catalog.db.events;
Defensive patterns

Strategy: validation

Validate before calling

val exists = spark.catalog.tableExists("cat.db.tbl") && spark.sql("SELECT * FROM cat.db.tbl.refs").collect().nonEmpty

Type guard

def isIcebergSparkTable(t: Any): Boolean = t.isInstanceOf[org.apache.iceberg.spark.source.SparkTable]

Try / catch

try { spark.sql("DROP TAG v1 IN cat.db.tbl") } catch { case e: UnsupportedOperationException if e.getMessage.startsWith("Cannot drop tag on non-Iceberg") => log.warn("skip non-Iceberg table") }

Prevention

When it happens

Trigger: Executing DROP TAG <tag> [IF EXISTS] on a table that does not match `iceberg: SparkTable` in DropTagExec.run().

Common situations: Tag DDL aimed at Delta/Hive/Parquet tables; misconfigured default catalog; migration scripts iterating over tables of mixed providers.

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/5175d1d47bd572f7. Report an issue: GitHub.

Appendix: source

Thrown at spark/v3.5/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/DropTagExec.scala:43

import org.apache.spark.sql.connector.catalog.TableCatalog

case class DropTagExec(catalog: TableCatalog, ident: Identifier, tag: String, ifExists: Boolean)
    extends LeafV2CommandExec {

  import org.apache.spark.sql.connector.catalog.CatalogV2Implicits._

  override lazy val output: Seq[Attribute] = Nil

  override protected def run(): Seq[InternalRow] = {
    catalog.loadTable(ident) match {
      case iceberg: SparkTable =>
        val ref = iceberg.table().refs().get(tag)
        if (ref != null || !ifExists) {
          iceberg.table().manageSnapshots().removeTag(tag).commit()
        }

      case table =>
        throw new UnsupportedOperationException(s"Cannot drop tag on non-Iceberg table: $table")
    }

    Nil
  }

  override def simpleString(maxFields: Int): String = {
    s"DropTag tag: ${tag} for table: ${ident.quoted}"
  }
}

View on GitHub (pinned to 86d9c8fc54)