apache/iceberg · error · IllegalStateException

Cannot load underlying Iceberg view for view: $ident

Error message

Cannot load underlying Iceberg view for view: $ident

What it means

This IllegalStateException is thrown by IcebergAlterV2ViewSetPropertiesExec when ViewUtil.loadIcebergView returns empty, i.e. the resolved view identifier exists to Spark but no underlying Iceberg view could be loaded from the catalog. Only views actually backed by Iceberg support ALTER VIEW ... SET PROPERTIES via this path.

Solutions

  1. Confirm the view was created as an Iceberg view (via Iceberg catalog DDL)
  2. Recreate the view under the Iceberg catalog, then set properties
  3. Check that the view still exists and the identifier matches (no replacement by a non-Iceberg view)
  4. Inspect ViewUtil.loadIcebergView behavior to ensure the catalog supports loading Iceberg views

Example fix

// before: view not backed by Iceberg
ALTER VIEW spark_catalog.db.v SET TBLPROPERTIES ('key'='val');
// after
ALTER VIEW iceberg_catalog.db.v SET TBLPROPERTIES ('key'='val');
Defensive patterns

Strategy: try-catch

Validate before calling

import org.apache.iceberg.spark.view.ViewUtil
ViewUtil.loadIcebergView(catalog, ident) match {
  case Some(_) => // safe to alter properties
  case None    => sys.error(s"$ident is not an Iceberg view")
}

Type guard

def isIcebergView(catalog: ViewCatalog, ident: Identifier): Boolean =
  ViewUtil.loadIcebergView(catalog, ident).isDefined

Try / catch

try { spark.sql("ALTER VIEW ... SET TBLPROPERTIES (...)") } catch {
  case e: IllegalStateException if e.getMessage.contains("Cannot load underlying Iceberg view") =>
    logError("view is not backed by Iceberg; recreate under the Iceberg catalog", e)
}

Prevention

When it happens

Trigger: Running 'ALTER VIEW ... SET PROPERTIES/SET TBLPROPERTIES' on a view registered in a ViewCatalog but whose underlying view is not an Iceberg view (loadIcebergView returns None).

Common situations: The view was created by another engine/provider and only registered in Spark; the catalog metadata changed or the view was replaced between resolution and execution; pointing ALTER VIEW at a temp or non-Iceberg view.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/ec57205a3fb62699. Report an issue: GitHub.

Appendix: source

Thrown at spark/v4.2/spark-extensions/src/main/scala/org/apache/spark/sql/execution/datasources/v2/IcebergAlterV2ViewSetPropertiesExec.scala:51

 * Uses a custom command instead of Spark's built-in implementation so Iceberg catalogs commit
 * property-only metadata updates and reject changes to reserved view properties.
 */
case class IcebergAlterV2ViewSetPropertiesExec(
    catalog: ViewCatalog,
    ident: Identifier,
    properties: Map[String, String])
    extends LeafV2CommandExec {

  override lazy val output: Seq[Attribute] = Nil

  override protected def run(): Seq[InternalRow] = {
    properties.keys.foreach(verifyNonReservedPropertyIsSet)

    val view =
      ViewUtil
        .loadIcebergView(catalog, ident)
        .getOrElse(
          throw new IllegalStateException(s"Cannot load underlying Iceberg view for view: $ident"))
    val update = view.updateProperties()
    properties.foreach { case (key, value) => update.set(key, value) }
    CommandUtils.uncacheTableOrView(session, ResolvedIdentifier(catalog, ident))
    update.commit()

    Nil
  }

  override def simpleString(maxFields: Int): String = {
    s"IcebergAlterV2ViewSetProperties: ${ident}"
  }

  private def verifyNonReservedPropertyIsSet(property: String): Unit = {
    if (SparkView.isReservedProperty(property)) {
      throw new UnsupportedOperationException(s"Cannot set reserved property: '$property'")
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)