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
JdbcCatalog.renameView throws AlreadyExistsException when the destination identifier collides with an existing TABLE. Views and tables share the identifier space in this catalog, so a view cannot be renamed onto an existing table name.
Source
Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java:724
public void renameView(TableIdentifier from, TableIdentifier to) {
if (schemaVersion != JdbcUtil.SchemaVersion.V1) {
throw new UnsupportedOperationException(VIEW_WARNING_LOG_MESSAGE);
}
if (from.equals(to)) {
return;
}
if (!namespaceExists(to.namespace())) {
throw new NoSuchNamespaceException("Namespace does not exist: %s", to.namespace());
}
if (!viewExists(from)) {
throw new NoSuchViewException("View does not exist");
}
if (tableExists(to)) {
throw new AlreadyExistsException("Cannot rename %s to %s. Table already exists", from, to);
}
if (viewExists(to)) {
throw new AlreadyExistsException("Cannot rename %s to %s. View already exists", from, to);
}
int updatedRecords =
execute(
err -> {
if (JdbcUtil.isConstraintViolation(err)) {
throw new AlreadyExistsException(
"Cannot rename %s to %s. View already exists", from, to);
}
},
JdbcUtil.RENAME_VIEW_SQL,
JdbcUtil.namespaceToString(to.namespace()),
to.name(),
catalogName,View on GitHub (pinned to 86d9c8fc54)
Solutions
- Choose a different destination name that does not collide with existing tables.
- Check catalog.tableExists(to) before renaming and pick an alternate name if taken.
- Drop the conflicting table first if it is truly obsolete (destructive — confirm first).
- Catch AlreadyExistsException and surface a clear conflict to the user.
Example fix
// before
catalog.renameView(from, to); // fails if a table named 'to' exists
// after
if (catalog.tableExists(to)) {
throw new IllegalStateException("Target name in use by a table: " + to);
}
catalog.renameView(from, to); Defensive patterns
Strategy: validation
Validate before calling
if (catalog.tableExists(to)) {
throw new IllegalArgumentException("Target name taken by table: " + to);
}
catalog.renameView(from, to); Try / catch
try {
catalog.renameView(from, to);
} catch (AlreadyExistsException e) {
// pick another destination name or surface conflict
} Prevention
- Check both tableExists and viewExists on the target before renaming
- Use name-generation that appends suffixes on collision
- Keep table and view naming conventions distinct
When it happens
Trigger: Calling catalog.renameView(from, to) where tableExists(to) is true — the target name is already taken by a table in the same namespace.
Common situations: Reusing a name that was previously a table, migrating tables to views (or vice versa) without cleaning up, generating target names programmatically that collide.
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
- View does not exist
- View with same name already exists: %s
- ViewAlreadyExistsException(toIdentifier)
- View already exists: ${toIdentifier}
- Cannot rename %s to %s. View does not exist
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/f9f4682461cb5474.
Report an issue: GitHub.