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
renameTableOrView() throws AlreadyExistsException when a view already exists at the rename destination identifier. Since Iceberg tables and views share the Hive Metastore namespace (distinguished by table type), a view at the destination also blocks a rename.
Source
Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java:410
private void renameTableOrView(
TableIdentifier from,
TableIdentifier originalTo,
HiveOperationsBase.ContentType contentType) {
Preconditions.checkArgument(isValidIdentifier(from), "Invalid identifier: %s", from);
TableIdentifier to = removeCatalogName(originalTo);
Preconditions.checkArgument(isValidIdentifier(to), "Invalid identifier: %s", to);
if (!namespaceExists(to.namespace())) {
throw new NoSuchNamespaceException(
"Cannot rename %s to %s. Namespace does not exist: %s", from, to, to.namespace());
}
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);
}
String toDatabase = to.namespace().level(0);
String fromDatabase = from.namespace().level(0);
String fromName = from.name();
try {
Table table = clients.run(client -> client.getTable(fromDatabase, fromName));
validateTableIsIcebergTableOrView(contentType, table, CatalogUtil.fullTableName(name, from));
table.setDbName(toDatabase);
table.setTableName(to.name());
clients.run(
client -> {
MetastoreUtil.alterTable(client, fromDatabase, fromName, table);
return null;
});View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check catalog.viewExists(to) before renaming and choose a different destination name.
- Drop the conflicting view first if it is no longer needed.
- In scripts, check both tableExists and viewExists for the destination.
- Use unique destination names to avoid races with concurrent view creation.
Example fix
// before
catalog.renameView(from, TableIdentifier.of(db, "summary"));
// after
TableIdentifier to = TableIdentifier.of(db, "summary");
if (catalog.viewExists(to) || catalog.tableExists(to)) {
throw new IllegalStateException("Destination name in use: " + to);
}
catalog.renameView(from, to); Defensive patterns
Strategy: validation
Validate before calling
TableIdentifier to = TableIdentifier.of(db, "summary");
if (catalog.viewExists(to) || catalog.tableExists(to)) {
throw new IllegalStateException("Destination name in use: " + to);
}
catalog.renameView(from, to); Try / catch
try {
catalog.renameView(from, to);
} catch (AlreadyExistsException e) {
// resolve view/table name collision, then retry
throw e;
} Prevention
- Check both viewExists and tableExists — tables and views share the HMS name space.
- Avoid reuse of historical names for tables/views without cleaning up first.
- Serialize rename workflows to prevent concurrent creations at the destination.
When it happens
Trigger: Calling catalog.renameTable(from, to) or catalog.renameView(from, to) where to passes the tableExists check but a Hive view (ICEBERG_VIEW type) named to.name() exists in to.namespace().
Common situations: A view with the intended table name exists (views and tables share the HMS name space); leftover views from earlier experiments; concurrent creation of a view at the destination; case-insensitive name collisions.
Related errors
- Cannot rename %s to %s. Table already exists
- Table already exists: %s
- Cannot rename table %s to %s: %s already exists
- Cannot rename %s to %s. View already exists
- Table already exists: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/7a23a2fc57d2f3d2.
Report an issue: GitHub.