apache/iceberg · error · AlreadyExistsException
Cannot rename %s to %s. Table already exists
Error message
Cannot rename %s to %s. Table already exists
What it means
InMemoryCatalog.renameTable throws AlreadyExistsException when a table already exists at the destination identifier. Renaming is not a merge; the catalog refuses to overwrite an existing table at 'to'.
Source
Thrown at core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java:182
@Override
public void renameTable(TableIdentifier from, TableIdentifier to) {
if (from.equals(to)) {
return;
}
synchronized (this) {
if (!namespaceExists(to.namespace())) {
throw new NoSuchNamespaceException(
"Cannot rename %s to %s. Namespace does not exist: %s", from, to, to.namespace());
}
String fromLocation = tables.get(from);
if (null == fromLocation) {
throw new NoSuchTableException("Cannot rename %s to %s. Table does not exist", from, to);
}
if (tables.containsKey(to)) {
throw new AlreadyExistsException("Cannot rename %s to %s. Table already exists", from, to);
}
if (views.containsKey(to)) {
throw new AlreadyExistsException("Cannot rename %s to %s. View already exists", from, to);
}
tables.put(to, fromLocation);
tables.remove(from);
}
}
@Override
public void createNamespace(Namespace namespace) {
createNamespace(namespace, Collections.emptyMap());
}
@Override
public void createNamespace(Namespace namespace, Map<String, String> metadata) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Drop or rename the existing destination table first
- Choose a unique destination identifier (e.g. append timestamp)
- Check catalog.tableExists(to) before renaming and handle collisions
- Catch AlreadyExistsException to skip if the destination already has the data
Example fix
// before
catalog.renameTable(from, to);
// after
if (!catalog.tableExists(to)) {
catalog.renameTable(from, to);
} else {
catalog.dropTable(to);
catalog.renameTable(from, to);
} Defensive patterns
Strategy: validation
Validate before calling
if (catalog.tableExists(to)) { catalog.dropTable(to); }
catalog.renameTable(from, to); Try / catch
try { catalog.renameTable(from, to); } catch (AlreadyExistsException e) { /* resolve collision: drop or pick new name */ } Prevention
- Generate unique destination names (timestamp/suffix)
- Check tableExists(to) before renaming
- Make backup/rotation jobs collision-aware
- Clean up stale destination tables in teardown
When it happens
Trigger: Calling catalog.renameTable(from, to) where tables already contains 'to'. E.g. renaming 'events' to 'events_backup' when 'events_backup' already exists from a previous rename.
Common situations: Cron jobs producing colliding backup names; retrying a partially completed rename workflow; test fixtures reusing names.
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 rename %s to %s. Namespace does not exist: %s
- Cannot rename %s to %s. Table does not exist
- Cannot rename %s to %s. View already exists
- Cannot rename table %s to %s: %s does not exist
- Cannot rename table %s to %s: %s already exists
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ba73c4bf4c2894bb.
Report an issue: GitHub.