apache/iceberg · error · 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

In stageDestTable, when destCatalog().stageCreate fails with Spark's NoSuchNamespaceException, BaseTableCreationSparkAction translates it into Iceberg's NoSuchNamespaceException stating the destination namespace does not exist. Iceberg does not auto-create namespaces during staged table creation.

Solutions

  1. Create the destination namespace first, e.g. spark.sql("CREATE NAMESPACE iceberg_catalog.ns")
  2. Verify the namespace name spelling and catalog in the destination identifier
  3. If using a Hadoop catalog, ensure the base warehouse location is writable so the namespace can be created

Example fix

// before
SparkActions.get(spark).snapshot("spark_catalog", "db.src", "iceberg.newns.dest").execute();
// after
spark.sql("CREATE NAMESPACE IF NOT EXISTS iceberg_catalog.newns");
SparkActions.get(spark).snapshot("spark_catalog", "db.src", "iceberg_catalog.newns.dest").execute();
Defensive patterns

Strategy: validation

Validate before calling

boolean nsExists = spark.sql("SHOW NAMESPACES IN " + destCatalog)
    .collectAsList().stream().anyMatch(r -> r.getString(0).equalsIgnoreCase(namespace));
if (!nsExists) spark.sql("CREATE NAMESPACE " + destCatalog + "." + namespace);

Try / catch

try { action.execute(); } catch (NoSuchNamespaceException e) { spark.sql("CREATE NAMESPACE IF NOT EXISTS " + destIdent.namespace()); action.execute(); }

Prevention

When it happens

Trigger: Executing snapshot/migrate/addFiles with a destination identifier whose namespace (database) has not been created in the destination catalog.

Common situations: Creating the destination in a fresh catalog where the namespace was never created; typo in destination namespace; Hadoop/Hive catalog pointing at a filesystem location without the namespace directory.

Related errors


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

Appendix: source

Thrown at spark/v3.5/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)