apache/iceberg · error · AlreadyExistsException
Table with same name already exists: %s
Error message
Table with same name already exists: %s
What it means
Before inserting a new view row, createView checks whether a TABLE with the same name already exists in the JDBC catalog. If it does, AlreadyExistsException is thrown, because Iceberg namespaces one object per name and a table/view name collision is unresolvable.
Source
Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcViewOperations.java:183
if (updatedRecords == 1) {
LOG.debug("Successfully committed to existing view: {}", viewIdentifier);
} else {
throw new CommitFailedException(
"Failed to update view %s from catalog %s", viewIdentifier, catalogName);
}
}
private void createView(String newMetadataLocation) throws SQLException, InterruptedException {
Namespace namespace = viewIdentifier.namespace();
if (PropertyUtil.propertyAsBoolean(catalogProperties, JdbcUtil.STRICT_MODE_PROPERTY, false)
&& !JdbcUtil.namespaceExists(catalogName, connections, namespace)) {
throw new NoSuchNamespaceException(
"Cannot create view %s in catalog %s. Namespace %s does not exist",
viewIdentifier, catalogName, namespace);
}
if (JdbcUtil.tableExists(JdbcUtil.SchemaVersion.V1, catalogName, connections, viewIdentifier)) {
throw new AlreadyExistsException("Table with same name already exists: %s", viewIdentifier);
}
if (JdbcUtil.viewExists(catalogName, connections, viewIdentifier)) {
throw new AlreadyExistsException("View already exists: %s", viewIdentifier);
}
int insertRecord =
JdbcUtil.doCommitCreateView(
connections, catalogName, namespace, viewIdentifier, newMetadataLocation);
if (insertRecord == 1) {
LOG.debug("Successfully committed to new view: {}", viewIdentifier);
} else {
throw new CommitFailedException(
"Failed to create view %s in catalog %s", viewIdentifier, catalogName);
}
}
}View on GitHub (pinned to 86d9c8fc54)
Solutions
- Choose a different name for the view, or drop the existing table first (catalog.dropTable(identifier))
- Check for the collision before creating: catalog.tableExists(identifier) / catalog.viewExists(identifier)
- Catch AlreadyExistsException to surface a friendly 'name in use' message to end users
- Clean up leftover tables from failed/aborted jobs in shared test environments
Example fix
// before
catalog.buildView(identify).createColumn(...).create();
// after
if (catalog.tableExists(identifier)) {
throw new IllegalArgumentException("Name in use by table: " + identifier);
}
catalog.buildView(identifier).createColumn(...).create(); Defensive patterns
Strategy: validation
Validate before calling
if (catalog.tableExists(identifier)) {
throw new IllegalArgumentException("Name in use by table: " + identifier);
} Try / catch
try {
catalog.buildView(id)...create();
} catch (AlreadyExistsException e) {
// surface 'name in use' to the user or pick a different name
} Prevention
- Check tableExists/viewExists before creating objects with reused names
- Drop stale tables from aborted jobs in shared environments
- Namespace your identifiers (job/owner prefix) to reduce collisions
When it happens
Trigger: Committing a new view (base == null) whose identifier collides with an existing table row in iceberg_tables for the same catalog and namespace.
Common situations: A name previously used for a table is reused for a view without dropping the table; cross-tool confusion where another engine created a table under the same identifier; test code reusing identifiers without cleanup.
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 create view %s in catalog %s. Namespace %s does not e
- Failed to create view %s in catalog %s
- Cannot create namespace %s: already exists
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/5f03b749e7fc24b0.
Report an issue: GitHub.