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
- Check catalog.tableExists(to) first; if it exists, decide whether to drop it, pick a different name, or treat the rename as done.
- Make retry logic idempotent: on AlreadyExistsException verify the destination's metadata location matches the source's and skip if the rename already completed.
- 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
- Pre-check the destination name before renaming
- Design rename retry logic to detect completed renames (source gone + destination present)
- Reserve/generate unique destination names in automated pipelines
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
- Cannot create namespace %s: already exists
- Cannot rename table %s to %s: %s does not exist
- Cannot find default warehouse location: namespace %s does no
- Cannot find namespace %s
- Cannot delete non-empty namespace %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/836a94605efc1275.
Report an issue: GitHub.