apache/iceberg · error · NoSuchViewException

View does not exist: %s

Error message

View does not exist: %s

What it means

HiveOperationsBase throws NoSuchViewException when a name resolves in the Hive Metastore to a valid Iceberg TABLE, but the caller requested it as a view. The HMS object exists, yet there is no Iceberg view at that identifier, so the view-load path fails. This enforces the table/view namespace separation in the Hive catalog.

Source

Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HiveOperationsBase.java:132

  static void validateTableIsIceberg(Table table, String fullName) {
    String tableType = table.getParameters().get(BaseMetastoreTableOperations.TABLE_TYPE_PROP);
    NoSuchIcebergTableException.check(
        isValidIcebergTable(table), "Not an iceberg table: %s (type=%s)", fullName, tableType);
  }

  static void validateTableIsIcebergView(Table table, String fullName) {
    String tableTypeProp = table.getParameters().get(BaseMetastoreTableOperations.TABLE_TYPE_PROP);
    NoSuchIcebergViewException.check(
        isValidIcebergView(table),
        "Not an iceberg view: %s (type=%s) (tableType=%s)",
        fullName,
        tableTypeProp,
        table.getTableType());
  }

  static void validateIcebergTableNotLoadedAsIcebergView(Table table, String fullName) {
    if (!isValidIcebergView(table) && isValidIcebergTable(table)) {
      throw new NoSuchViewException("View does not exist: %s", fullName);
    }
  }

  static void validateIcebergViewNotLoadedAsIcebergTable(Table table, String fullName) {
    if (!isValidIcebergTable(table) && isValidIcebergView(table)) {
      throw new NoSuchTableException("Table does not exist: %s", fullName);
    }
  }

  default void persistTable(Table hmsTable, boolean updateHiveTable, String metadataLocation)
      throws TException, InterruptedException {
    if (updateHiveTable) {
      metaClients()
          .run(
              client -> {
                MetastoreUtil.alterTable(
                    client, database(), table(), hmsTable, hmsEnvContext(metadataLocation));
                return null;

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Load the identifier as a table instead: catalog.loadTable(identifier) — the object exists and is an Iceberg table.
  2. Verify the intended view name; create the view if it does not exist via catalog.buildView(...).create().
  3. Check the HMS entity (describe formatted / HiveCatalog) to confirm whether it is a table or view and correct the call site.

Example fix

// before
View view = catalog.loadView(TableIdentifier.of("db", "events")); // events is a table
// after
Table table = catalog.loadTable(TableIdentifier.of("db", "events"));
Defensive patterns

Strategy: try-catch

Validate before calling

if (catalog.tableExists(ident) && !catalog.viewExists(ident)) { /* load as table */ }

Try / catch

try { view = catalog.loadView(ident); } catch (NoSuchViewException e) { table = catalog.loadTable(ident); }

Prevention

When it happens

Trigger: Calling loadView/loadTable-as-view (e.g. HiveCatalog.loadView or view-related validation) on an identifier that actually refers to an Iceberg table registered in HMS; validateIcebergTableNotLoadedAsIcebergView detects isValidIcebergTable(table) && !isValidIcebergView(table).

Common situations: Typo or copy-paste reusing a table name for a view; code migrated from table APIs to view APIs without renaming; an existing Iceberg table at the same catalog.database.name target where a view was expected.

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/2213dab64e04d35d. Report an issue: GitHub.