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

  1. Drop all child namespaces recursively before dropping the parent
  2. List children with listNamespaces(namespace) and iterate dropNamespace
  3. Drop tables in each child namespace first to avoid chained NotEmpty errors
  4. 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

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/65a727ecbb4a2924. Report an issue: GitHub.