apache/iceberg · error · NoSuchTableException

Table does not exist: %s

Error message

Table does not exist: %s

What it means

HiveOperationsBase throws NoSuchTableException when the HMS entry is a valid Iceberg VIEW but the caller requested it as a table. The identifier resolves in the metastore, but not to an Iceberg table, so the table-load path fails. It is the mirror of validateIcebergTableNotLoadedAsIcebergView.

Source

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

  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;
              });
    } else {
      metaClients()
          .run(
              client -> {
                client.createTable(hmsTable);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Load it as a view instead: catalog.loadView(identifier).
  2. If a table is intended, choose a different name and create the table, since the name is occupied by a view.
  3. Drop or rename the existing view in HMS if the identifier should hold a table.

Example fix

// before
Table table = catalog.loadTable(TableIdentifier.of("db", "summary")); // it's a view
// after
View view = catalog.loadView(TableIdentifier.of("db", "summary"));
Defensive patterns

Strategy: try-catch

Validate before calling

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

Try / catch

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

Prevention

When it happens

Trigger: Calling catalog.loadTable(identifier) on a name that is registered as an Iceberg view in HMS; validateIcebergViewNotLoadedAsIcebergTable detects !isValidIcebergTable(table) && isValidIcebergView(table).

Common situations: A view was created at the same name after the code expected a table; renaming an entity from view to table in code while the HMS object stayed a view; loading all entities of a database assuming tables.

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/67b6691237dba733. Report an issue: GitHub.