apache/iceberg · error · AlreadyExistsException
Table with same name already exists: %s
Error message
Table with same name already exists: %s
What it means
HiveCatalog's table-builder createOrReplace() throws AlreadyExistsException when a table (not a view) already exists under the target identifier. createOrReplace on a view builder refuses to clobber an existing table — replacing a table with a view would destroy data, so it is a hard error. The tableExists check runs before any replacement metadata is committed.
Source
Thrown at hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java:943
/**
* The purpose of this class is to add table detection only for Hive-Specific view. Hive catalog
* follows checks at different levels: 1. During refresh, it validates if the view is an iceberg
* view or not. 2. During commit, it validates if there is any concurrent commit with view or
* view-name already exists. This class helps to do the validation on an early basis.
*/
private class TableAwareViewBuilder extends BaseViewBuilder {
private final TableIdentifier identifier;
private TableAwareViewBuilder(TableIdentifier identifier) {
super(identifier);
this.identifier = identifier;
}
@Override
public View createOrReplace() {
if (tableExists(identifier)) {
throw new AlreadyExistsException("Table with same name already exists: %s", identifier);
}
return super.createOrReplace();
}
@Override
public View create() {
if (tableExists(identifier)) {
throw new AlreadyExistsException("Table with same name already exists: %s", identifier);
}
return super.create();
}
}
/**
* Register a table with the catalog if it does not exist. This is overridden in order to add view
* existence detection before registering a table.
*
* @param identifier a table identifierView on GitHub (pinned to 86d9c8fc54)
Solutions
- Drop the existing table explicitly: catalog.dropTable(identifier) (consider purge semantics) before creating the view.
- Choose a distinct identifier for the view so it doesn't collide with the table.
- Catch AlreadyExistsException and surface a clear operator message about the table/view name collision.
- Audit the namespace for name collisions before running view-creation migrations.
Example fix
// before
catalog.buildView(identifier).createOrReplace(); // collides with existing table
// after
if (catalog.tableExists(identifier)) {
catalog.dropTable(identifier);
}
catalog.buildView(identifier).createOrReplace(); Defensive patterns
Strategy: validation
Validate before calling
if (catalog.tableExists(identifier)) {
throw new IllegalStateException("Name " + identifier + " is occupied by a table; cannot create view");
} Try / catch
try {
catalog.buildView(identifier).createOrReplace();
} catch (AlreadyExistsException e) {
// drop the table explicitly after human confirmation, then retry
} Prevention
- Never reuse the same identifier for tables and views
- Audit namespaces for name collisions before migrations
- Drop the old table explicitly when converting a table to a view
When it happens
Trigger: Calling HiveCatalog.buildView(identifier).createOrReplace() when a table with the same namespace/name exists (tableExists(identifier) is true). Typically a name collision where the same logical name was previously created as a table.
Common situations: Migrating a dataset from a table to a view without dropping the table first; a naming convention change that collides an old table name with a new view name; automated scripts reusing one identifier for both artifacts.
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 with same name already exists: %s
- View already exists: %s
- Cannot rename %s to %s. View already exists
- Cannot create namespace %s: already exists
- Cannot rename table %s to %s: %s already exists
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/33eadeaae3cc8e83.
Report an issue: GitHub.