apache/iceberg · error · AlreadyExistsException
Cannot create table as it already exists
Error message
Cannot create table %s as it already exists
What it means
Failure in BaseTableCreationSparkAction.stageDestTable: staging the destination table creation threw TableAlreadyExistsException (the %s is the destination identifier), rethrown as the action's already-exists error. It fires when CTAS/RTAS-style actions target an existing table without replace semantics.
Solutions
- Choose a new destination name via .as("db.new_name") or drop the existing destination table
- If it is a leftover backup/staged table from a failed run, drop it or restore it before re-running
- Check catalog contents with SHOW TABLES IN <catalog>.<ns> to confirm the name is free
Example fix
// before
SparkActions.get(spark).migrateTable("db.tbl").as("iceberg_db.tbl").execute(); // tbl exists
// after
SparkActions.get(spark).migrateTable("db.tbl").as("iceberg_db.tbl_migrated").execute(); Defensive patterns
Strategy: try-catch
Validate before calling
boolean exists = spark.catalog().tableExists(destIdentString);
if (exists) { dropOrRenameDestFirst(); } Try / catch
try { action.execute(); } catch (AlreadyExistsException e) { /* drop backup or pick new .as() name and retry */ } Prevention
- Use unique destination names per run
- Clean up leftover backup/staged tables after failed runs
- Check SHOW TABLES before running
When it happens
Trigger: Calling migrateTable(...).as(existingIdent) (or snapshot to an existing name) where the destination catalog already contains that table name; stageCreate throws TableAlreadyExistsException.
Common situations: Re-running a failed/partial migration without cleaning up the staged destination table; a backup table from a previous migrate run already occupying the name.
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
- Cannot create table as the namespace does not exist
- Cannot rename as for backup. The backup table already…
- Cannot rename as for backup. The backup table already…
- Namespace already exists
- NamespaceAlreadyExistsException(namespace)
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/0295954da94d784f.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/actions/BaseTableCreationSparkAction.java:167
catalog.getClass().getName(),
SparkSessionCatalog.class.getName(),
SparkCatalog.class.getName());
return (StagingTableCatalog) catalog;
}
protected StagedSparkTable stageDestTable() {
try {
Map<String, String> props = destTableProps();
StructType schema = sourceTable.schema();
Transform[] partitioning = sourceTable.partitioning();
return (StagedSparkTable)
destCatalog().stageCreate(destTableIdent(), schema, partitioning, props);
} catch (org.apache.spark.sql.catalyst.analysis.NoSuchNamespaceException e) {
throw new NoSuchNamespaceException(
"Cannot create table %s as the namespace does not exist", destTableIdent());
} catch (org.apache.spark.sql.catalyst.analysis.TableAlreadyExistsException e) {
throw new AlreadyExistsException(
"Cannot create table %s as it already exists", destTableIdent());
}
}
protected void ensureNameMappingPresent(Table table) {
if (!table.properties().containsKey(TableProperties.DEFAULT_NAME_MAPPING)) {
NameMapping nameMapping = MappingUtil.create(table.schema());
String nameMappingJson = NameMappingParser.toJson(nameMapping);
table.updateProperties().set(TableProperties.DEFAULT_NAME_MAPPING, nameMappingJson).commit();
}
}
protected String getMetadataLocation(Table table) {
String defaultValue =
LocationUtil.stripTrailingSlash(table.location()) + "/" + ICEBERG_METADATA_FOLDER;
return LocationUtil.stripTrailingSlash(
table.properties().getOrDefault(TableProperties.WRITE_METADATA_LOCATION, defaultValue));
}View on GitHub (pinned to 86d9c8fc54)