apache/iceberg · error · NamespaceNotEmptyException
Namespace is not empty. Contains child namespace(s).
Error message
Namespace %s is not empty. Contains %d child namespace(s).
What it means
dropNamespace throws NamespaceNotEmptyException when the namespace still contains child namespaces. The JDBC catalog only allows dropping empty namespaces to prevent accidental loss of namespaced tables. The count of child namespaces is included in the message.
Solutions
- Drop all child namespaces first (recursively, bottom-up), then drop the parent
- Drop or migrate all tables and views under the namespace before retrying
- Catch NamespaceNotEmptyException in cleanup code and enumerate/drop contents programmatically
Example fix
// before
catalog.dropNamespace(ns);
// after
for (Namespace child : catalog.listNamespaces(ns)) {
catalog.dropNamespace(child);
}
catalog.dropNamespace(ns); Defensive patterns
Strategy: validation
Validate before calling
if (!catalog.listNamespaces(ns).isEmpty()) { throw new IllegalStateException("namespace has children"); } Type guard
boolean dropSafe = catalog.listNamespaces(ns).isEmpty() && catalog.listTables(ns).isEmpty();
Try / catch
try { catalog.dropNamespace(ns); } catch (NamespaceNotEmptyException e) { /* recursively drop children then retry */ } Prevention
- Drop namespaces bottom-up (children first)
- Write recursive teardown helpers rather than assuming flat layouts
- Purge tables and views before namespace cleanup in environment teardown scripts
When it happens
Trigger: Calling catalog.dropNamespace(ns) while listNamespaces(ns) returns one or more child namespaces.
Common situations: Tearing down environments top-down without dropping leaf namespaces first; recursive namespace hierarchies created accidentally; cleanup scripts assuming a flat namespace layout.
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
- Namespace already exists
- Namespace is not empty. Contains table(s).
- Namespace is not empty. Contains view(s).
- Can not alter the default database when the iceberg catalog…
- Cannot apply unknown namespace change
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/cafd48be7a28f926.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java:548
}
private String defaultNamespaceLocation(Namespace namespace) {
if (namespace.isEmpty()) {
return warehouseLocation;
} else {
return SLASH.join(warehouseLocation, SLASH.join(namespace.levels()));
}
}
@Override
public boolean dropNamespace(Namespace namespace) throws NamespaceNotEmptyException {
if (!namespaceExists(namespace)) {
return false;
}
List<Namespace> childNamespaces = listNamespaces(namespace);
if (childNamespaces != null && !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 != null && !tableIdentifiers.isEmpty()) {
throw new NamespaceNotEmptyException(
"Namespace %s is not empty. Contains %d table(s).", namespace, tableIdentifiers.size());
}
if (schemaVersion != JdbcUtil.SchemaVersion.V0) {
List<TableIdentifier> viewIdentifiers = listViews(namespace);
if (viewIdentifiers != null && !viewIdentifiers.isEmpty()) {
throw new NamespaceNotEmptyException(
"Namespace %s is not empty. Contains %d view(s).", namespace, viewIdentifiers.size());
}
}
View on GitHub (pinned to 86d9c8fc54)