apache/iceberg · error · AlreadyExistsException
Cannot rename %s to %s. View already exists
Error message
Cannot rename %s to %s. View already exists
What it means
JdbcCatalog.renameTable throws AlreadyExistsException when renaming a table to a name that collides with an existing view under the V1 schema. This guards the single-catalog-namespace against name collisions between tables and views in V1-backed JDBC catalogs. The rename is aborted before any SQL update is issued.
Source
Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java:369
JdbcUtil.namespaceToString(namespace));
}
@Override
public void renameTable(TableIdentifier from, TableIdentifier to) {
if (from.equals(to)) {
return;
}
if (!tableExists(from)) {
throw new NoSuchTableException("Table does not exist: %s", from);
}
if (!namespaceExists(to.namespace())) {
throw new NoSuchNamespaceException("Namespace does not exist: %s", to.namespace());
}
if (schemaVersion == JdbcUtil.SchemaVersion.V1 && viewExists(to)) {
throw new AlreadyExistsException("Cannot rename %s to %s. View already exists", from, to);
}
if (tableExists(to)) {
throw new AlreadyExistsException("Table already exists: %s", to);
}
int updatedRecords =
execute(
err -> {
if (JdbcUtil.isConstraintViolation(err)) {
throw new AlreadyExistsException("Table already exists: %s", to);
}
},
(schemaVersion == JdbcUtil.SchemaVersion.V1)
? JdbcUtil.V1_RENAME_TABLE_SQL
: JdbcUtil.V0_RENAME_TABLE_SQL,
JdbcUtil.namespaceToString(to.namespace()),
to.name(),View on GitHub (pinned to 86d9c8fc54)
Solutions
- Choose a different target TableIdentifier that does not collide with an existing view
- Drop or rename the existing view at the target name first, then retry renameTable
- If view/table sharing a name is intended, migrate the catalog to the V0 (shared-identifier) schema version where this check is not applied
Example fix
// before
catalog.renameTable(from, TableIdentifier.of(ns, "report")); // fails: view 'report' exists
// after
if (!catalog.listViews(ns).contains(TableIdentifier.of(ns, "report"))) {
catalog.renameTable(from, TableIdentifier.of(ns, "report"));
} Defensive patterns
Strategy: try-catch
Validate before calling
if (catalog instanceof JdbcCatalog && catalog.listViews(to.namespace()).contains(to)) { throw new IllegalStateException("target collides with view"); } Type guard
boolean targetIsFree = !catalog.tableExists(to) && !catalog.listViews(to.namespace()).contains(to);
Try / catch
try { catalog.renameTable(from, to); } catch (AlreadyExistsException e) { /* pick a new target name or drop the view */ } Prevention
- Check both tableExists and listViews for the target identifier before renaming
- Avoid giving views and tables identical names in shared namespaces
- Document the catalog schema version in use since V0 and V1 differ on this check
When it happens
Trigger: Calling catalog.renameTable(from, to) where 'to' names an existing view and the JDBC catalog schemaVersion is V1 (V1_RENAME_TABLE_SQL used, catalog_property 'catalog-table'/'catalog-view' separated).
Common situations: Migrating catalogs where a view was created at the target name; upgrading or downgrading JDBC schema versions where V1 separated views and tables but identifiers still overlap; concurrent creation of a view between the caller's exists-check and rename.
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
- Table already exists: %s
- Cannot rename table %s to %s: %s already exists
- Namespace already exists: %s
- Cannot rename %s to %s. Table already exists
- Cannot rename %s to %s. View already exists
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/31a40ac2001ff641.
Report an issue: GitHub.