apache/iceberg · error · IllegalArgumentException

listNamespaces must be at either ROOT or DATABASE level; got

Error message

listNamespaces must be at either ROOT or DATABASE level; got %s from namespace %s

What it means

SnowflakeCatalog.listNamespaces can only enumerate databases (ROOT scope) or schemas (DATABASE scope). A namespace resolving to SCHEMA or TABLE scope reaches the default branch and throws IllegalArgumentException, because Snowflake has no third namespace level to list.

Solutions

  1. Only call listNamespaces with Namespace.empty() or a single-level (database) namespace
  2. Treat a two-level namespace as a leaf: stop recursion at schema level
  3. Check namespace.levels().length <= 1 before invoking listNamespaces

Example fix

// before
catalog.listNamespaces(Namespace.of("db", "schema")); // throws
// after
if (namespace.levels().length <= 1) {
  catalog.listNamespaces(namespace);
}
Defensive patterns

Strategy: validation

Validate before calling

if (namespace.levels().length > 1) {
  throw new IllegalArgumentException(
      "listNamespaces supports only ROOT or DATABASE level: " + namespace);
}

Type guard

boolean isListableNamespace(Namespace ns) {
  return ns != null && ns.levels().length <= 1;
}

Try / catch

try {
  catalog.listNamespaces(namespace);
} catch (IllegalArgumentException e) {
  // stop recursion: schema-level namespaces have no children here
}

Prevention

When it happens

Trigger: Calling listNamespaces(Namespace.of("db","schema")) — schema-level listing is not supported; the input namespace must be empty (ROOT) or exactly one level (DATABASE).

Common situations: Generic catalog explorers that recursively list nested namespaces; code ported from Hive/Hadoop catalogs listing children of a schema; tooling iterating all namespace levels.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at snowflake/src/main/java/org/apache/iceberg/snowflake/SnowflakeCatalog.java:189

  @Override
  public void createNamespace(Namespace namespace, Map<String, String> metadata) {
    throw new UnsupportedOperationException(
        "SnowflakeCatalog does not currently support createNamespace");
  }

  @Override
  public List<Namespace> listNamespaces(Namespace namespace) {
    SnowflakeIdentifier scope = NamespaceHelpers.toSnowflakeIdentifier(namespace);
    List<SnowflakeIdentifier> results;
    switch (scope.type()) {
      case ROOT:
        results = snowflakeClient.listDatabases();
        break;
      case DATABASE:
        results = snowflakeClient.listSchemas(scope);
        break;
      default:
        throw new IllegalArgumentException(
            String.format(
                "listNamespaces must be at either ROOT or DATABASE level; got %s from namespace %s",
                scope, namespace));
    }

    return results.stream().map(NamespaceHelpers::toIcebergNamespace).collect(Collectors.toList());
  }

  @Override
  public Map<String, String> loadNamespaceMetadata(Namespace namespace)
      throws NoSuchNamespaceException {
    SnowflakeIdentifier id = NamespaceHelpers.toSnowflakeIdentifier(namespace);
    boolean namespaceExists;
    switch (id.type()) {
      case DATABASE:
        namespaceExists = snowflakeClient.databaseExists(id);
        break;
      case SCHEMA:

View on GitHub (pinned to 86d9c8fc54)