apache/iceberg · error · NoSuchTableException
Table does not exist: %s
Error message
Table does not exist: %s
What it means
The catalog resolved the identifier's namespace, but TableOperations.current() returned null — meaning no valid metadata exists at that location — and the name is also not a valid metadata-table identifier. NoSuchTableException is thrown so callers can distinguish 'missing table' from other load failures.
Source
Thrown at core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java:55
import org.slf4j.LoggerFactory;
public abstract class BaseMetastoreCatalog implements Catalog, Closeable {
private static final Logger LOG = LoggerFactory.getLogger(BaseMetastoreCatalog.class);
private MetricsReporter metricsReporter;
@Override
public Table loadTable(TableIdentifier identifier) {
Table result;
if (isValidIdentifier(identifier)) {
TableOperations ops = newTableOps(identifier);
if (ops.current() == null) {
// the identifier may be valid for both tables and metadata tables
if (isValidMetadataIdentifier(identifier)) {
result = loadMetadataTable(identifier);
} else {
throw new NoSuchTableException("Table does not exist: %s", identifier);
}
} else {
result = new BaseTable(ops, fullTableName(name(), identifier), metricsReporter());
}
} else if (isValidMetadataIdentifier(identifier)) {
result = loadMetadataTable(identifier);
} else {
throw new NoSuchTableException("Invalid table identifier: %s", identifier);
}
LOG.info("Table loaded by catalog: {}", result);
return result;
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Verify the identifier and namespace are correct and the catalog URI points to the right metastore
- Check table existence with catalog.tableExists(identifier) before loading
- Recreate the table or restore its metadata if it was dropped accidentally
- Register the table from a surviving metadata.json via catalog.registerTable if the metadata file still exists
Example fix
// before
Table table = catalog.loadTable(TableIdentifier.of("db", "events")); // NoSuchTableException
// after
TableIdentifier ident = TableIdentifier.of("db", "events");
if (catalog.tableExists(ident)) {
Table table = catalog.loadTable(ident);
} else {
table = catalog.registerTable(ident, metadataFileLocation);
} Defensive patterns
Strategy: try-catch
Validate before calling
Preconditions.checkArgument(catalog.tableExists(ident) , "Table does not exist: " + ident);
Try / catch
try { return catalog.loadTable(ident); } catch (NoSuchTableException e) { logger.warn("Table missing: {}", ident, e); return createOrRegister(ident); } Prevention
- Verify identifiers against catalog.listTables() before loading
- Watch for out-of-band drops in the metastore
- Distinguish 'create new' vs 'load existing' paths with tableExists
When it happens
Trigger: catalog.loadTable(identifier) where the table was never created, was dropped, the identifier has an invalid namespace/name combination, or the underlying metadata location is empty.
Common situations: Typos in table name or namespace; stale references after DROP TABLE; Hadoop/Hive metastore entries removed out-of-band; wrong catalog selected for the identifier.
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
- Invalid table identifier: %s
- No such table: %s
- No such table: %s
- No such table: %s
- Cannot find source table %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/10a26326ecf5f36e.
Report an issue: GitHub.