apache/iceberg · error · org.apache.iceberg.exceptions.NoSuchNamespaceException

Cannot create table as the namespace does not exist

Error message

Cannot create table %s as the namespace does not exist

What it means

When staging the destination table for migrate/snapshot actions, destCatalog().stageCreate throws Spark's NoSuchNamespaceException if the destination namespace does not exist. The action converts it into Iceberg's NoSuchNamespaceException with this message. The destination database must exist before staging the new table.

Solutions

  1. Create the destination namespace first: CREATE NAMESPACE <catalog>.<ns>
  2. Check the destination identifier for typos in the namespace part
  3. Verify you are pointing at the intended catalog (spark.sql.catalog.<name>)

Example fix

// before
CALL iceberg.system.migrate('prod_db.new_iceberg_tbl') -- prod_db missing in iceberg catalog
// after
CREATE NAMESPACE iceberg.prod_db;
CALL iceberg.system.migrate('prod_db.new_iceberg_tbl');
Defensive patterns

Strategy: validation

Validate before calling

// Ensure destination namespace exists before migrating
SHOW NAMESPACES IN iceberg; // or
CREATE NAMESPACE IF NOT EXISTS iceberg.prod_db;

Try / catch

try { ... } catch (NoSuchNamespaceException e) { spark.sql("CREATE NAMESPACE " + ns); retry(); }

Prevention

When it happens

Trigger: Running MIGRATE or SNAPSHOT with a destination identifier whose namespace (database) does not exist in the destination catalog, e.g. CALL system.migrate('db.new_table') where db is missing.

Common situations: Typo in the destination database name; running against a new catalog where the namespace was never created; case sensitivity mismatch in namespace names.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/actions/BaseTableCreationSparkAction.java:164

        "Cannot create Iceberg table in non-Iceberg Catalog. "
            + "Catalog '%s' was of class '%s' but '%s' or '%s' are required",
        catalog.name(),
        catalog.getClass().getName(),
        SparkSessionCatalog.class.getName(),
        SparkCatalog.class.getName());

    return (StagingTableCatalog) catalog;
  }

  protected StagedSparkTable stageDestTable() {
    try {
      Map<String, String> props = destTableProps();
      StructType schema = sourceTable.schema();
      Transform[] partitioning = sourceTable.partitioning();
      return (StagedSparkTable)
          destCatalog().stageCreate(destTableIdent(), schema, partitioning, props);
    } catch (org.apache.spark.sql.catalyst.analysis.NoSuchNamespaceException e) {
      throw new NoSuchNamespaceException(
          "Cannot create table %s as the namespace does not exist", destTableIdent());
    } catch (org.apache.spark.sql.catalyst.analysis.TableAlreadyExistsException e) {
      throw new AlreadyExistsException(
          "Cannot create table %s as it already exists", destTableIdent());
    }
  }

  protected void ensureNameMappingPresent(Table table) {
    if (!table.properties().containsKey(TableProperties.DEFAULT_NAME_MAPPING)) {
      NameMapping nameMapping = MappingUtil.create(table.schema());
      String nameMappingJson = NameMappingParser.toJson(nameMapping);
      table.updateProperties().set(TableProperties.DEFAULT_NAME_MAPPING, nameMappingJson).commit();
    }
  }

  protected String getMetadataLocation(Table table) {
    String defaultValue =
        LocationUtil.stripTrailingSlash(table.location()) + "/" + ICEBERG_METADATA_FOLDER;

View on GitHub (pinned to 86d9c8fc54)