apache/iceberg · error · RuntimeException
Cannot create namespace '%s': %s
Error message
Cannot create namespace '%s': %s
What it means
This is the catch-all in NessieIcebergClient.createNamespace: any NessieConflictException that isn't KEY_EXISTS or NAMESPACE_ABSENT (or other unhandled commit conflicts) is wrapped in a RuntimeException formatted as 'Cannot create namespace %s: <conflict message>'. It surfaces server-side conflict details without a typed Iceberg exception.
Source
Thrown at nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java:251
Optional<Conflict> conflict =
NessieUtil.extractSingleConflict(
e,
EnumSet.of(
Conflict.ConflictType.KEY_EXISTS, Conflict.ConflictType.NAMESPACE_ABSENT));
if (conflict.isPresent()) {
switch (conflict.get().conflictType()) {
case KEY_EXISTS:
Content conflicting = withReference(api.getContent()).key(key).get().get(key);
throw namespaceAlreadyExists(key, conflicting, e);
case NAMESPACE_ABSENT:
throw new NoSuchNamespaceException(
e,
"Cannot create namespace '%s': parent namespace '%s' does not exist",
namespace,
conflict.get().key());
}
}
throw new RuntimeException(
String.format("Cannot create namespace '%s': %s", namespace, e.getMessage()));
}
} catch (NessieNotFoundException e) {
throw new UncheckedIOException(
String.format(
"Cannot create namespace '%s': ref '%s' is no longer valid.",
namespace, getRef().getName()),
e);
} catch (BaseNessieClientServerException e) {
throw new UncheckedIOException(
String.format("Cannot create namespace '%s': %s", namespace, e.getMessage()), e);
}
}
public List<Namespace> listNamespaces(Namespace namespace) throws NoSuchNamespaceException {
try {
String filter = "entry.contentType == 'NAMESPACE' && ";
if (namespace.isEmpty()) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Retry the createNamespace after refreshing the catalog/client so it commits against the latest ref hash.
- Serialize namespace creation (avoid multiple processes creating the same namespace concurrently), or tolerate a RuntimeException as 'someone else created it' and verify with namespaceExists.
- Inspect the wrapped message for the underlying Nessie conflict and fix per its cause (e.g. switch to the correct branch).
Example fix
// before
catalog.createNamespace(ns); // RuntimeException on conflict
// after
try {
catalog.createNamespace(ns);
} catch (RuntimeException e) {
if (catalog.namespaceExists(ns)) {
// created concurrently; proceed
} else {
throw e;
}
} Defensive patterns
Strategy: retry
Validate before calling
// minimize conflict windows: refresh ref state before committing api.reference().refName(branch).get(); // confirm current hash before createNamespace
Try / catch
try {
catalog.createNamespace(ns);
} catch (RuntimeException e) {
if (catalog.namespaceExists(ns)) {
// concurrent creation; treat as success
} else {
throw e;
}
} Prevention
- Avoid concurrent namespace creation on the same branch
- Re-create the catalog (fresh client/ref hash) before retrying after conflicts
- Treat generic conflicts as 'maybe created concurrently' and verify with namespaceExists
When it happens
Trigger: Calling createNamespace while the Nessie server reports an unexpected conflict type — e.g. concurrent commits to the same branch producing a generic Conflict, ref hash changed (update on stale ref), or server-side validation errors other than KEY_EXISTS/NAMESPACE_ABSENT.
Common situations: Concurrent writers committing namespaces/tables to the same branch simultaneously; branch was force-updated between client reads and the commit; using a detached/tag ref that disallows the operation.
Related errors
- Cannot drop namespace '%s': %s
- Cannot update properties on namespace '%s': %s
- Cannot create namespace '%s': parent namespace '%s' does not
- Namespace '%s' is not empty.
- Namespace already exists: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1efa3a2a50a5041d.
Report an issue: GitHub.