apache/iceberg · error · NoSuchTableException
Invalid table identifier: %s
Error message
Invalid table identifier: %s
What it means
When loading a table whose identifier is not valid for the catalog (and not a valid metadata identifier), the catalog reports it as NoSuchTableException with 'Invalid table identifier'. It fires on the branch where the identifier itself cannot denote a table in this catalog, e.g. an empty/invalid name for the catalog's namespace handling.
Source
Thrown at core/src/main/java/org/apache/iceberg/BaseMetastoreCatalog.java:66
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;
}
@Override
public Table registerTable(TableIdentifier identifier, String metadataFileLocation) {
Preconditions.checkArgument(
identifier != null && isValidIdentifier(identifier), "Invalid identifier: %s", identifier);
Preconditions.checkArgument(
metadataFileLocation != null && !metadataFileLocation.isEmpty(),
"Cannot register an empty metadata file location as a table");
// Throw an exception if this table already exists in the catalog.
if (tableExists(identifier)) {
throw new AlreadyExistsException("Table already exists: %s", identifier);
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Validate the TableIdentifier (non-empty namespace levels and name) before calling loadTable
- Ensure the namespace depth matches the catalog's expected hierarchy
- Use the correct catalog instance for the namespace layout
Example fix
// before TableIdentifier bad = TableIdentifier.of(namespace); // name missing Table t = catalog.loadTable(bad); // after ValidationException.check(!name.isEmpty(), "Table name required"); TableIdentifier ident = TableIdentifier.of(namespace, name); Table t = catalog.loadTable(ident);
Defensive patterns
Strategy: validation
Validate before calling
ValidationException.check(identifier != null && !identifier.name().isEmpty() && identifier.namespace().levels().length > 0, "Invalid identifier: " + identifier);
Type guard
boolean isValid(TableIdentifier id) { return id != null && !id.name().isEmpty() && id.namespace().levels().length > 0; } Try / catch
try { return catalog.loadTable(ident); } catch (NoSuchTableException e) { throw new IllegalArgumentException("Bad table identifier: " + ident, e); } Prevention
- Build identifiers with TableIdentifier.of using explicit name and namespace
- Match namespace depth to the catalog's metastore layout
- Add identifier validation at application boundaries
When it happens
Trigger: loadTable with an identifier whose name is invalid (e.g. empty name) or whose namespace cannot form a valid table identifier for this catalog, and which is not a metadata-table name.
Common situations: Programmatic identifier construction producing empty names; mixing catalogs with different namespace semantics (e.g. nested namespaces on a two-level Hive metastore).
Related errors
- No such table: %s
- Table does not exist: %s
- Invalid identifier: %s
- No such table: %s
- Invalid view identifier: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/e57075f9c969eaa7.
Report an issue: GitHub.