apache/iceberg · error · NoSuchNamespaceException

Cannot list top-level namespaces: ref '%s' is no longer vali

Error message

Cannot list top-level namespaces: ref '%s' is no longer valid.

What it means

When listing top-level namespaces (empty namespace argument), a NessieNotFoundException from the entries/get-content call means the pinned reference itself no longer exists. The client converts it into NoSuchNamespaceException 'Cannot list top-level namespaces: ref ... is no longer valid.' The reference is stale or was deleted server-side.

Source

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

      }
      List<ContentKey> entries =
          withReference(api.getEntries()).filter(filter).stream()
              .map(EntriesResponse.Entry::getName)
              .collect(Collectors.toList());
      if (entries.isEmpty()) {
        return Collections.emptyList();
      }
      GetContentBuilder getContent = withReference(api.getContent());
      entries.forEach(getContent::key);
      return getContent.get().values().stream()
          .map(v -> v.unwrap(org.projectnessie.model.Namespace.class))
          .filter(Optional::isPresent)
          .map(Optional::get)
          .map(v -> Namespace.of(v.getElements().toArray(new String[0])))
          .collect(Collectors.toList());
    } catch (NessieNotFoundException e) {
      if (namespace.isEmpty()) {
        throw new NoSuchNamespaceException(
            e,
            "Cannot list top-level namespaces: ref '%s' is no longer valid.",
            getRef().getName());
      }
      throw new NoSuchNamespaceException(
          e,
          "Cannot list child namespaces from '%s': ref '%s' is no longer valid.",
          namespace,
          getRef().getName());
    }
  }

  public boolean dropNamespace(Namespace namespace) throws NamespaceNotEmptyException {
    checkNamespaceIsValid(namespace);
    getRef().checkMutable();
    ContentKey key = ContentKey.of(namespace.levels());
    try {
      Map<ContentKey, Content> contentMap =

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Confirm the reference exists on the Nessie server and recreate it if missing.
  2. Fix the 'ref' value in the catalog configuration (typo or removed branch).
  3. Rebuild/reload the catalog so the reference is re-resolved to current HEAD.

Example fix

// before
conf.put("ref", "daily-etag"); // tag GC'ed on server
List<Namespace> ns = catalog.listNamespaces(); // throws
// after
conf.put("ref", "main"); // stable branch
Defensive patterns

Strategy: validation

Validate before calling

boolean refExists = api.getAllReferences().get().getReferences().stream()
    .anyMatch(r -> r.getName().equals(configuredRef));
if (!refExists) throw new IllegalStateException("Ref missing: " + configuredRef);

Try / catch

try {
  return catalog.listNamespaces();
} catch (NoSuchNamespaceException e) {
  if (e.getMessage().contains("no longer valid")) return rebuildCatalogAndList();
  throw e;
}

Prevention

When it happens

Trigger: Calling Catalog.listNamespaces() (no args) against a Nessie catalog whose configured branch/tag was deleted after the catalog was instantiated.

Common situations: Long-lived Spark session holding a catalog bound to a branch that CI later deleted; typos in the ref name in catalog config; garbage-collected tags.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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