apache/iceberg · error · NoSuchNamespaceException
Cannot create table %s. Namespace does not exist: %s
Error message
Cannot create table %s. Namespace does not exist: %s
What it means
InMemoryCatalog's table commit path (doCommit in the inner table operator) validates that the table's namespace exists before creating a new table (base == null). Iceberg requires the parent namespace to be created explicitly via createNamespace; it never auto-creates namespaces. If the namespace is missing, NoSuchNamespaceException is thrown and the metadata file already written is effectively abandoned.
Source
Thrown at core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java:432
@Override
public void doRefresh() {
String latestLocation = tables.get(tableIdentifier);
if (latestLocation == null) {
disableRefresh();
} else {
refreshFromMetadataLocation(latestLocation);
}
}
@Override
public void doCommit(TableMetadata base, TableMetadata metadata) {
String newLocation = writeNewMetadataIfRequired(base == null, metadata);
String oldLocation = base == null ? null : base.metadataFileLocation();
synchronized (InMemoryCatalog.this) {
if (null == base && !namespaceExists(tableIdentifier.namespace())) {
throw new NoSuchNamespaceException(
"Cannot create table %s. Namespace does not exist: %s",
tableIdentifier, tableIdentifier.namespace());
}
if (views.containsKey(tableIdentifier)) {
throw new AlreadyExistsException(
"View with same name already exists: %s", tableIdentifier);
}
tables.compute(
tableIdentifier,
(k, existingLocation) -> {
if (!Objects.equal(existingLocation, oldLocation)) {
if (null == base) {
throw new AlreadyExistsException("Table already exists: %s", tableName());
}
if (null == existingLocation) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Call catalog.createNamespace(ident.namespace()) before createTable.
- Guard with namespaceExists: if (!catalog.namespaceExists(ns)) catalog.createNamespace(ns).
- Use createOrReplace/create if the catalog API offers an auto-create variant for your flow.
- Verify the namespace spelling matches what was registered.
Example fix
// before
catalog.createTable(TableIdentifier.of("analytics", "events"), schema);
// after
Namespace ns = Namespace.of("analytics");
if (!catalog.namespaceExists(ns)) {
catalog.createNamespace(ns);
}
catalog.createTable(TableIdentifier.of("analytics", "events"), schema); Defensive patterns
Strategy: validation
Validate before calling
Namespace ns = ident.namespace();
if (!catalog.namespaceExists(ns)) {
catalog.createNamespace(ns);
} Try / catch
try { catalog.createTable(ident, schema); } catch (NoSuchNamespaceException e) { catalog.createNamespace(ident.namespace()); catalog.createTable(ident, schema); } Prevention
- Create namespaces during environment/test setup before any table creation
- Wrap table creation in a ensureNamespace helper
- Double-check namespace spelling against registered namespaces
When it happens
Trigger: Calling catalog.createTable(ident, schema) (or any operation that triggers a first commit) where ident.namespace() was never registered via catalog.createNamespace(...).
Common situations: Forgetting to create namespaces in tests or local in-memory setups; migrating code from catalogs that auto-create namespaces (e.g. some Hadoop setups); typo in namespace name; environment reset that cleared the in-memory catalog between steps.
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
- Namespace does not exist: %s
- Namespace already exists: %s
- Cannot set namespace properties " + namespace + " : setPrope
- Cannot remove properties " + namespace + " : removePropertie
- Namespace %s is not empty. Contains %d table(s).
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/21869a7d4e35fd3e.
Report an issue: GitHub.