apache/iceberg · error · NamespaceAlreadyExistsException

NamespaceAlreadyExistsException(namespace)

Error message

NamespaceAlreadyExistsException(namespace)

What it means

createNamespace was called on a catalog where the namespace already exists; the Iceberg AlreadyExistsException was caught and rethrown as Spark's NamespaceAlreadyExistsException. Iceberg catalogs enforce namespace uniqueness and do not create-if-absent silently.

Source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkCatalog.java:519

    throw new NoSuchNamespaceException(namespace);
  }

  @Override
  public void createNamespace(String[] namespace, Map<String, String> metadata)
      throws NamespaceAlreadyExistsException {
    if (asNamespaceCatalog != null) {
      try {
        if (asNamespaceCatalog instanceof HadoopCatalog
            && DEFAULT_NS_KEYS.equals(metadata.keySet())) {
          // Hadoop catalog will reject metadata properties, but Spark automatically adds "owner".
          // If only the automatic properties are present, replace metadata with an empty map.
          asNamespaceCatalog.createNamespace(Namespace.of(namespace), ImmutableMap.of());
        } else {
          asNamespaceCatalog.createNamespace(Namespace.of(namespace), metadata);
        }
      } catch (AlreadyExistsException e) {
        throw new NamespaceAlreadyExistsException(namespace);
      }
    } else {
      throw new UnsupportedOperationException(
          "Namespaces are not supported by catalog: " + catalogName);
    }
  }

  @Override
  public void alterNamespace(String[] namespace, NamespaceChange... changes)
      throws NoSuchNamespaceException {
    if (asNamespaceCatalog != null) {
      Map<String, String> updates = Maps.newHashMap();
      Set<String> removals = Sets.newHashSet();
      for (NamespaceChange change : changes) {
        if (change instanceof NamespaceChange.SetProperty) {
          NamespaceChange.SetProperty set = (NamespaceChange.SetProperty) change;
          updates.put(set.property(), set.value());
        } else if (change instanceof NamespaceChange.RemoveProperty) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use CREATE NAMESPACE IF NOT EXISTS in SQL, or check namespaceExists before calling createNamespace.
  2. Catch NamespaceAlreadyExistsException and treat it as success in idempotent setup code.
  3. Serialize bootstrap jobs (locking/orchestration) to avoid concurrent-create races.
  4. Remove the pre-existing namespace first if recreation is truly intended.

Example fix

// before
catalog.createNamespace(new String[] {"analytics"}); // throws if exists

// after
String[] ns = {"analytics"};
if (!catalog.namespaceExists(ns)) {
  catalog.createNamespace(ns);
}
Defensive patterns

Strategy: validation

Validate before calling

String[] ns = {"analytics"};
if (!catalog.namespaceExists(ns)) {
  catalog.createNamespace(ns, metadata);
}

Try / catch

try {
  catalog.createNamespace(ns, metadata);
} catch (NamespaceAlreadyExistsException e) {
  // idempotent bootstrap: treat as success
}

Prevention

When it happens

Trigger: CREATE NAMESPACE catalog.ns where ns already exists; idempotent setup scripts that rerun createNamespace without an existence check; two concurrent jobs racing to create the same namespace; earlier partial pipeline run already created it.

Common situations: IF NOT EXISTS forgotten in DDL; Terraform/setup scripts executed twice; multi-engine setups where Spark and Flink both bootstrap the same namespaces.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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