apache/iceberg · error · AlreadyExistsException

Cannot rename table %s to %s: %s already exists

Error message

Cannot rename table %s to %s: %s already exists

What it means

DynamoDbCatalog.renameTable() checks that the destination table does not exist before writing the new item; if the GetItem for the `to` key finds an item it throws AlreadyExistsException with this message. This prevents renaming a table onto an existing one and silently overwriting its metadata.

Source

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

                .consistentRead(true)
                .key(fromKey)
                .build());

    if (!fromResponse.hasItem()) {
      throw new NoSuchTableException(
          "Cannot rename table %s to %s: %s does not exist", from, to, from);
    }

    GetItemResponse toResponse =
        dynamo.getItem(
            GetItemRequest.builder()
                .tableName(awsProperties.dynamoDbTableName())
                .consistentRead(true)
                .key(toKey)
                .build());

    if (toResponse.hasItem()) {
      throw new AlreadyExistsException(
          "Cannot rename table %s to %s: %s already exists", from, to, to);
    }

    fromResponse.item().entrySet().stream()
        .filter(e -> isProperty(e.getKey()))
        .forEach(e -> toKey.put(e.getKey(), e.getValue()));

    setNewCatalogEntryMetadata(toKey);

    dynamo.transactWriteItems(
        TransactWriteItemsRequest.builder()
            .transactItems(
                TransactWriteItem.builder()
                    .delete(
                        Delete.builder()
                            .tableName(awsProperties.dynamoDbTableName())
                            .key(fromKey)
                            .conditionExpression(COL_VERSION + " = :v")

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check catalog.tableExists(to) first; if it exists, decide whether to drop it, pick a different name, or treat the rename as done.
  2. Make retry logic idempotent: on AlreadyExistsException verify the destination's metadata location matches the source's and skip if the rename already completed.
  3. Remove or rename the existing destination table if it is confirmed stale.

Example fix

// before
catalog.renameTable(from, to);

// after
if (!catalog.tableExists(to)) {
  catalog.renameTable(from, to);
}
Defensive patterns

Strategy: validation

Validate before calling

if (catalog.tableExists(to)) {
  throw new IllegalStateException("Destination " + to + " already exists; choose another name or drop it");
}
catalog.renameTable(from, to);

Try / catch

try {
  catalog.renameTable(from, to);
} catch (AlreadyExistsException e) {
  // possibly a completed retry; verify destination metadata before rethrowing
  if (!catalog.tableExists(from)) return; // rename already finished
  throw e;
}

Prevention

When it happens

Trigger: Calling catalog.renameTable(from, to) when an item for the `to` identifier already exists in the DynamoDB catalog table.

Common situations: Retrying a failed rename that actually completed (destination written before source delete); two concurrent renames to the same target name; re-running a migration script that already renamed the table.

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/836a94605efc1275. Report an issue: GitHub.