apache/iceberg · error · NoSuchNamespaceException

Namespace %s does not exist

Error message

Namespace %s does not exist

What it means

EcsCatalog.listTables first verifies the namespace exists (by checking for its namespace marker object in ECS) and throws NoSuchNamespaceException otherwise. Callers must create the namespace before listing its tables. dropNamespace and other flows that call listTables can surface this error.

Source

Thrown at dell/src/main/java/org/apache/iceberg/dell/ecs/EcsCatalog.java:155

  protected TableOperations newTableOps(TableIdentifier tableIdentifier) {
    return new EcsTableOperations(
        String.format("%s.%s", catalogName, tableIdentifier),
        tableURI(tableIdentifier),
        fileIO,
        this);
  }

  @Override
  protected String defaultWarehouseLocation(TableIdentifier tableIdentifier) {
    String tableLocation = LocationUtil.tableLocation(tableIdentifier, uniqueTableLocation);
    return String.format("%s/%s", namespacePrefix(tableIdentifier.namespace()), tableLocation);
  }

  /** Iterate all table objects with the namespace prefix. */
  @Override
  public List<TableIdentifier> listTables(Namespace namespace) {
    if (!namespace.isEmpty() && !namespaceExists(namespace)) {
      throw new NoSuchNamespaceException("Namespace %s does not exist", namespace);
    }

    String marker = null;
    List<TableIdentifier> results = Lists.newArrayList();
    // Add the end slash when delimiter listing
    EcsURI prefix = new EcsURI(String.format("%s/", namespacePrefix(namespace)));
    do {
      ListObjectsResult listObjectsResult =
          client.listObjects(
              new ListObjectsRequest(prefix.bucket())
                  .withDelimiter("/")
                  .withPrefix(prefix.name())
                  .withMarker(marker));
      marker = listObjectsResult.getNextMarker();
      results.addAll(
          listObjectsResult.getObjects().stream()
              .filter(s3Object -> s3Object.getKey().endsWith(TABLE_OBJECT_SUFFIX))
              .map(object -> parseTableId(namespace, prefix, object))

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check catalog.namespaceExists(namespace) before calling listTables, or catch NoSuchNamespaceException.
  2. Create the namespace with catalog.createNamespace(namespace) first.
  3. Correct the namespace spelling/hierarchy to match the existing ECS prefix.

Example fix

// before
List<TableIdentifier> tables = catalog.listTables(Namespace.of("sales"));
// after
if (catalog.namespaceExists(Namespace.of("sales"))) {
  List<TableIdentifier> tables = catalog.listTables(Namespace.of("sales"));
}
Defensive patterns

Strategy: try-catch

Validate before calling

Namespace ns = Namespace.of("a", "b");
if (!catalog.namespaceExists(ns)) { catalog.createNamespace(ns); }

Try / catch

try {
  return catalog.listTables(ns);
} catch (NoSuchNamespaceException e) {
  return Collections.emptyList();
}

Prevention

When it happens

Trigger: Calling catalog.listTables(Namespace.of("a","b")) when no table/namespace marker objects exist under that prefix, or after the namespace was deleted; dropNamespace invoking listTables on an already-removed namespace.

Common situations: Typo in namespace levels; querying a namespace created outside this catalog (without its marker object); race where another job dropped the namespace concurrently.

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/1fd49944569fa3e5. Report an issue: GitHub.