apache/iceberg · error · AlreadyExistsException

Cannot create namespace %s: already exists

Error message

Cannot create namespace %s: already exists

What it means

DynamoDbCatalog.createNamespace() writes a new namespace item with a condition expression `attribute_not_exists(...)`. If the item already exists, DynamoDB raises ConditionalCheckFailedException, which is translated into this AlreadyExistsException. This keeps namespace creation idempotent-safe and prevents silent overwrites.

Source

Thrown at aws/src/main/java/org/apache/iceberg/aws/dynamodb/DynamoDbCatalog.java:217

  }

  @Override
  public void createNamespace(Namespace namespace, Map<String, String> metadata) {
    validateNamespace(namespace);
    Map<String, AttributeValue> values = namespacePrimaryKey(namespace);
    setNewCatalogEntryMetadata(values);
    metadata.forEach(
        (key, value) -> values.put(toPropertyCol(key), AttributeValue.builder().s(value).build()));

    try {
      dynamo.putItem(
          PutItemRequest.builder()
              .tableName(awsProperties.dynamoDbTableName())
              .conditionExpression("attribute_not_exists(" + DynamoDbCatalog.COL_VERSION + ")")
              .item(values)
              .build());
    } catch (ConditionalCheckFailedException e) {
      throw new AlreadyExistsException("Cannot create namespace %s: already exists", namespace);
    }
  }

  @Override
  public List<Namespace> listNamespaces(Namespace namespace) throws NoSuchNamespaceException {
    validateNamespace(namespace);
    List<Namespace> namespaces = Lists.newArrayList();
    Map<String, AttributeValue> lastEvaluatedKey = null;
    String condition = COL_IDENTIFIER + " = :identifier";
    Map<String, AttributeValue> conditionValues = Maps.newHashMap();
    conditionValues.put(
        ":identifier", AttributeValue.builder().s(COL_IDENTIFIER_NAMESPACE).build());
    if (!namespace.isEmpty()) {
      condition += " AND " + "begins_with(" + COL_NAMESPACE + ",:ns)";
      conditionValues.put(":ns", AttributeValue.builder().s(namespace.toString()).build());
    }

    do {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check existence first with catalog.namespaceExists(namespace) before calling createNamespace.
  2. Catch org.apache.iceberg.exceptions.AlreadyExistsException and treat it as success in idempotent setup code.
  3. Inspect the existing namespace item to confirm it is not a stale/conflicting entry before deleting it deliberately.

Example fix

// before
catalog.createNamespace(Namespace.of("analytics"));

// after
if (!catalog.namespaceExists(Namespace.of("analytics"))) {
  catalog.createNamespace(Namespace.of("analytics"));
}
Defensive patterns

Strategy: validation

Validate before calling

if (catalog.namespaceExists(namespace)) {
  return; // already created, skip
}
catalog.createNamespace(namespace);

Try / catch

try {
  catalog.createNamespace(namespace);
} catch (AlreadyExistsException e) {
  // idempotent: treat as success
}

Prevention

When it happens

Trigger: Calling catalog.createNamespace(namespace) when a row with the same namespace primary key already exists in the DynamoDB catalog table — including multi-level namespaces sharing the same partition key (e.g. creating `a.b` after `a.b.c` exists).

Common situations: Two concurrent jobs both creating the same namespace; rerunning an idempotent setup script without existence checks; nested-namespace collisions where a shorter namespace already occupies the key; stale catalog caches making callers believe the namespace is absent.

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/80e353cc860705b1. Report an issue: GitHub.