apache/iceberg · error · NamespaceNotEmptyException
Namespace %s is not empty. Contains %d child namespace(s).
Error message
Namespace %s is not empty. Contains %d child namespace(s).
What it means
InMemoryCatalog.dropNamespace throws NamespaceNotEmptyException when the namespace still contains child namespaces. The catalog refuses to drop a namespace that would orphan nested namespaces, forcing explicit removal of children first.
Source
Thrown at core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java:225
namespaces.put(namespace, ImmutableMap.copyOf(metadata));
}
}
@Override
public boolean namespaceExists(Namespace namespace) {
return namespaces.containsKey(namespace);
}
@Override
public boolean dropNamespace(Namespace namespace) throws NamespaceNotEmptyException {
synchronized (this) {
if (!namespaceExists(namespace)) {
return false;
}
List<Namespace> childNamespaces = listNamespaces(namespace);
if (!childNamespaces.isEmpty()) {
throw new NamespaceNotEmptyException(
"Namespace %s is not empty. Contains %d child namespace(s).",
namespace, childNamespaces.size());
}
List<TableIdentifier> tableIdentifiers = listTables(namespace);
if (!tableIdentifiers.isEmpty()) {
throw new NamespaceNotEmptyException(
"Namespace %s is not empty. Contains %d table(s).", namespace, tableIdentifiers.size());
}
List<TableIdentifier> viewIdentifiers = listViews(namespace);
if (!viewIdentifiers.isEmpty()) {
throw new NamespaceNotEmptyException(
"Namespace %s is not empty. Contains %d view(s).", namespace, viewIdentifiers.size());
}
return namespaces.remove(namespace) != null;
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Drop all child namespaces recursively before dropping the parent
- List children with listNamespaces(namespace) and iterate dropNamespace
- Drop tables in each child namespace first to avoid chained NotEmpty errors
- Catch NamespaceNotEmptyException if partial cleanup is acceptable
Example fix
// before
catalog.dropNamespace(Namespace.of("parent"));
// after
Namespace ns = Namespace.of("parent");
for (Namespace child : catalog.listNamespaces(ns)) {
catalog.dropNamespace(child);
}
catalog.dropNamespace(ns); Defensive patterns
Strategy: validation
Validate before calling
if (!catalog.listNamespaces(namespace).isEmpty()) { throw new IllegalStateException("Drop child namespaces first"); }
catalog.dropNamespace(namespace); Try / catch
try { catalog.dropNamespace(ns); } catch (NamespaceNotEmptyException e) { /* recursively drop children then retry */ } Prevention
- Write recursive teardown: drop tables, then child namespaces, then parent
- List children with listNamespaces before dropping
- Order cleanup deepest-first in hierarchical namespaces
- Model cleanup as a helper so no path skips nested namespaces
When it happens
Trigger: Calling catalog.dropNamespace(ns) when listNamespaces(ns) returns one or more child namespaces. E.g. dropping 'a' while 'a.b' still exists.
Common situations: Hierarchical namespace layouts (multi-level namespaces) where cleanup only removed tables but not nested namespaces; teardown scripts running in the wrong order.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot drop namespace %s because it still contains Iceberg t
- Cannot drop namespace %s because it still contains non-Icebe
- %s is not empty: %s
- Namespace %s is not empty.
- Cannot list tables for namespace. Namespace does not exist:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/65a727ecbb4a2924.
Report an issue: GitHub.