apache/iceberg · error · NoSuchNamespaceException

Namespace does not exist: %s

Error message

Namespace does not exist: %s

What it means

NoSuchNamespaceException thrown by JdbcCatalog.listTables when the given Namespace has no rows in the iceberg_namespace_properties table — i.e. the namespace was never created or was dropped. listTables refuses to return an empty list for unknown namespaces so callers can distinguish 'empty' from 'nonexistent'.

Source

Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java:340

            identifier.name());

    if (deletedRecords == 0) {
      LOG.info("Skipping drop, table does not exist: {}", identifier);
      return false;
    }

    if (purge && lastMetadata != null) {
      CatalogUtil.dropTableData(ops.io(), lastMetadata);
    }

    LOG.info("Dropped table: {}", identifier);
    return true;
  }

  @Override
  public List<TableIdentifier> listTables(Namespace namespace) {
    if (!namespaceExists(namespace)) {
      throw new NoSuchNamespaceException("Namespace does not exist: %s", namespace);
    }

    return fetch(
        row ->
            JdbcUtil.stringToTableIdentifier(
                row.getString(JdbcUtil.TABLE_NAMESPACE), row.getString(JdbcUtil.TABLE_NAME)),
        (schemaVersion == JdbcUtil.SchemaVersion.V1)
            ? JdbcUtil.V1_LIST_TABLE_SQL
            : JdbcUtil.V0_LIST_TABLE_SQL,
        catalogName,
        JdbcUtil.namespaceToString(namespace));
  }

  @Override
  public void renameTable(TableIdentifier from, TableIdentifier to) {
    if (from.equals(to)) {
      return;
    }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Create the namespace first with catalog.createNamespace(namespace)
  2. Verify the namespace name spelling and case (Postgres stores it as given)
  3. Confirm you are connected to the JDBC database that actually holds the namespace
  4. Use listNamespaces() to discover existing namespace names before listing tables

Example fix

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

Strategy: try-catch

Validate before calling

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

Type guard

boolean safeToList(Catalog c, Namespace ns) { return c.namespaceExists(ns); }

Try / catch

try {
  tables = catalog.listTables(ns);
} catch (NoSuchNamespaceException e) {
  catalog.createNamespace(ns);
  tables = List.of();
}

Prevention

When it happens

Trigger: Calling catalog.listTables(Namespace.of("...")) for a namespace that was never created via createNamespace, was already dropped, or whose name differs in case from what was created.

Common situations: Typo or case mismatch in the namespace name, querying before createNamespace in bootstrap code, a catalog pointed at the wrong database/warehouse, or a concurrent drop between namespaceExists and the query.

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/540ee7b8aba3f47e. Report an issue: GitHub.