apache/iceberg · error · NoSuchNamespaceException

Cannot create namespace '%s': parent namespace '%s' does not

Error message

Cannot create namespace '%s': parent namespace '%s' does not exist

What it means

createNamespace commits a namespace (as a content key) to Nessie. When the Nessie server responds with a NAMESPACE_ABSENT conflict, the client translates it into NoSuchNamespaceException saying the parent namespace doesn't exist — you cannot create a nested namespace whose parent path was never created.

Source

Thrown at nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java:244

      Content existing = api.getContent().reference(getReference()).key(key).get().get(key);
      if (existing != null) {
        throw namespaceAlreadyExists(key, existing, null);
      }
      try {
        commitRetry("create namespace " + key, Operation.Put.of(key, content));
      } catch (NessieReferenceConflictException e) {
        Optional<Conflict> conflict =
            NessieUtil.extractSingleConflict(
                e,
                EnumSet.of(
                    Conflict.ConflictType.KEY_EXISTS, Conflict.ConflictType.NAMESPACE_ABSENT));
        if (conflict.isPresent()) {
          switch (conflict.get().conflictType()) {
            case KEY_EXISTS:
              Content conflicting = withReference(api.getContent()).key(key).get().get(key);
              throw namespaceAlreadyExists(key, conflicting, e);
            case NAMESPACE_ABSENT:
              throw new NoSuchNamespaceException(
                  e,
                  "Cannot create namespace '%s': parent namespace '%s' does not exist",
                  namespace,
                  conflict.get().key());
          }
        }
        throw new RuntimeException(
            String.format("Cannot create namespace '%s': %s", namespace, e.getMessage()));
      }
    } catch (NessieNotFoundException e) {
      throw new UncheckedIOException(
          String.format(
              "Cannot create namespace '%s': ref '%s' is no longer valid.",
              namespace, getRef().getName()),
          e);
    } catch (BaseNessieClientServerException e) {
      throw new UncheckedIOException(
          String.format("Cannot create namespace '%s': %s", namespace, e.getMessage()), e);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Create parent namespaces first, in order: createNamespace(Namespace.of("a")), then Namespace.of("a","b"), then the target.
  2. Or use a flat (single-level) namespace if hierarchical scoping isn't required.
  3. If the parent was deleted concurrently, re-create it before retrying the child namespace creation.

Example fix

// before
catalog.createNamespace(Namespace.of("a", "b", "c")); // NoSuchNamespaceException
// after
catalog.createNamespace(Namespace.of("a"));
catalog.createNamespace(Namespace.of("a", "b"));
catalog.createNamespace(Namespace.of("a", "b", "c"));
Defensive patterns

Strategy: validation

Validate before calling

// ensure every parent level exists before creating a nested namespace
Namespace ns = Namespace.of("a", "b", "c");
for (int i = 1; i <= ns.levels().length; i++) {
  Namespace parent = Namespace.of(Arrays.copyOf(ns.levels(), i));
  if (!catalog.namespaceExists(parent)) catalog.createNamespace(parent);
}

Try / catch

try {
  catalog.createNamespace(ns);
} catch (NoSuchNamespaceException e) {
  // create parents first, then retry
  createParentsInOrder(ns);
  catalog.createNamespace(ns);
}

Prevention

When it happens

Trigger: Calling NessieCatalog.createNamespace for a multi-level namespace like 'a.b.c' when 'a.b' (or 'a') has not been created yet; Nessie commit fails with Conflict/NAMESPACE_ABSENT and the client wraps it.

Common situations: Creating deep namespaces in one call instead of level by level; parent namespace deleted concurrently by another process; assuming Iceberg auto-creates parent namespaces on Nessie-backed catalogs.

Related errors


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