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
- Use CREATE NAMESPACE IF NOT EXISTS in SQL, or check namespaceExists before calling createNamespace.
- Catch NamespaceAlreadyExistsException and treat it as success in idempotent setup code.
- Serialize bootstrap jobs (locking/orchestration) to avoid concurrent-create races.
- 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
- Use CREATE NAMESPACE IF NOT EXISTS in SQL
- Make bootstrap scripts idempotent via existence checks or catch-and-continue
- Serialize concurrent namespace-creation jobs
- Verify preconditions after failed pipeline reruns
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
- Namespace already exists: ${namespace}
- Namespace already exists: %s
- No such namespace: %s
- NoSuchNamespaceException(namespace)
- TableAlreadyExistsException(to)
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4b6a3078962327a4.
Report an issue: GitHub.