apache/iceberg · error · RuntimeException

Failed to check table existence of ${baseTableIdentifier}

Error message

Failed to check table existence of ${baseTableIdentifier}

What it means

A RuntimeException wrapping a Thrift TException raised while HiveCatalog.tableExists probes the metastore for a table. Iceberg treats NoSuchTableException/NoSuchObjectException as a normal 'false' answer, but any other Thrift failure (connectivity, server error) is unexpected and wrapped with this message. The original exception is the cause.

Source

Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java:497

    TableIdentifier baseTableIdentifier = identifier;
    if (!isValidIdentifier(identifier)) {
      if (!isValidMetadataIdentifier(identifier)) {
        return false;
      } else {
        baseTableIdentifier = TableIdentifier.of(identifier.namespace().levels());
      }
    }

    String database = baseTableIdentifier.namespace().level(0);
    String tableName = baseTableIdentifier.name();
    try {
      Table table = clients.run(client -> client.getTable(database, tableName));
      HiveOperationsBase.validateTableIsIceberg(table, fullTableName(name, baseTableIdentifier));
      return true;
    } catch (NoSuchTableException | NoSuchObjectException e) {
      return false;
    } catch (TException e) {
      throw new RuntimeException("Failed to check table existence of " + baseTableIdentifier, e);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new RuntimeException(
          "Interrupted in call to check table existence of " + baseTableIdentifier, e);
    }
  }

  @Override
  public boolean viewExists(TableIdentifier viewIdentifier) {
    if (!isValidIdentifier(viewIdentifier)) {
      return false;
    }

    String database = viewIdentifier.namespace().level(0);
    String viewName = viewIdentifier.name();
    try {
      Table table = clients.run(client -> client.getTable(database, viewName));
      HiveOperationsBase.validateTableIsIcebergView(table, fullTableName(name, viewIdentifier));

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Inspect e.getCause() for the Thrift root cause (transport vs server error).
  2. Verify metastore availability, URIs, and credentials (Kerberos/DelegationToken) then retry.
  3. Cache existence checks in hot paths to reduce metastore load and transient failure exposure.

Example fix

// before
boolean exists = catalog.tableExists(identifier);
// after
boolean exists;
try {
  exists = catalog.tableExists(identifier);
} catch (RuntimeException e) {
  throw new RuntimeException("Metastore unreachable while checking " + identifier, e.getCause());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check metastore reachability
// e.g. socket connect to metastore host:port before bulk existence checks

Try / catch

try { boolean ok = catalog.tableExists(id); } catch (RuntimeException e) { /* treat as unknown; inspect e.getCause() (TException) */ }

Prevention

When it happens

Trigger: Calling tableExists(identifier), or any code path that uses it (renameTableOrView, registerTable), when the metastore call client.getTable(...) fails with a TException other than not-found.

Common situations: Metastore downtime during job startup; network partitions; Kerberos/authentication failures surfacing as TTransportException; metastore overload under heavy existence-check traffic.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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