apache/iceberg · error · NoSuchTableException
No such table: .
Error message
No such table: %s.%s
What it means
HiveTableOperations.doRefresh throws NoSuchTableException when the Hive metastore reports NoSuchObjectException during refresh, but this operations object already holds a metadata location (i.e., the table existed earlier and now vanished). It signals the table was dropped concurrently or between operations.
Solutions
- Re-check the table existence in HMS; recreate it if the drop was unintended.
- Retry the catalog operation after confirming the table was recreated (fresh loadTable).
- Coordinate drop operations with readers/writers (locks or job orchestration) to avoid concurrent removal.
Example fix
// before
Table t = catalog.loadTable(ident); ... long job ...; t.refresh(); // table dropped meanwhile -> NoSuchTableException
// after
if (catalog.tableExists(ident)) { t = catalog.loadTable(ident); } else { /* recreate or abort */ } Defensive patterns
Strategy: retry
Validate before calling
if (!catalog.tableExists(ident)) { throw new NoSuchTableException("Table dropped: " + ident); } // check before long jobs Try / catch
try { table.refresh(); } catch (NoSuchTableException e) { if (catalog.tableExists(ident)) { table = catalog.loadTable(ident); table.refresh(); } else { /* recreate or abort */ } } Prevention
- Coordinate drops with active readers/writers.
- Re-verify existence after long-running stages.
- Use drop-and-recreate pipelines that publish atomically.
When it happens
Trigger: Refreshing (loadTable → any scan/commit path triggering doRefresh) while another process drops the HMS table; HMS get_table returning NoSuchObjectException with currentMetadataLocation() != null.
Common situations: Concurrent drop-and-recreate pipelines; a different job dropping the table mid-read; cluster tools (e.g. drop cascades) removing the table during a long-running job.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Interrupted during refresh
- Cannot commit: Base metadata location
- Cannot commit: Base metadata location
- Cannot find Glue table
- Cannot rename to . Namespace does not exist
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/e5df3a7825c25349.
Report an issue: GitHub.
Appendix: source
Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HiveTableOperations.java:193
try {
Table table = metaClients.run(client -> client.getTable(database, tableName));
// Check if we are trying to load an Iceberg View as a Table
HiveOperationsBase.validateIcebergViewNotLoadedAsIcebergTable(table, fullName);
// Check if it is a valid Iceberg Table
HiveOperationsBase.validateTableIsIceberg(table, fullName);
metadataLocation = table.getParameters().get(METADATA_LOCATION_PROP);
/* Table key ID must be retrieved from a catalog service, and not from untrusted storage
(e.g. metadata json file) that can be tampered with. For example, an attacker can remove
the table key parameter (along with existing snapshots) in the file, making the writers
produce unencrypted files. Table key ID is taken directly from HMS catalog */
tableKeyIdFromHMS = table.getParameters().get(TableProperties.ENCRYPTION_TABLE_KEY);
dekLengthFromHMS = table.getParameters().get(TableProperties.ENCRYPTION_DEK_LENGTH);
metadataHashFromHMS = table.getParameters().get(METADATA_HASH_PROP);
} catch (NoSuchObjectException e) {
if (currentMetadataLocation() != null) {
throw new NoSuchTableException("No such table: %s.%s", database, tableName);
}
} catch (TException e) {
String errMsg =
String.format("Failed to get table info from metastore %s.%s", database, tableName);
throw new RuntimeException(errMsg, e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted during refresh", e);
}
refreshFromMetadataLocation(metadataLocation, metadataRefreshMaxRetries);
if (tableKeyIdFromHMS != null) {
checkIntegrityForEncryption(tableKeyIdFromHMS, dekLengthFromHMS, metadataHashFromHMS);
tableKeyId = tableKeyIdFromHMS;View on GitHub (pinned to 86d9c8fc54)