apache/iceberg · error · AlreadyExistsException
Cannot rename as for backup. The backup table already…
Error message
Cannot rename %s as %s for backup. The backup table already exists.
What it means
During MigrateTable, the source table is renamed to a backup identifier. If a table already exists under that backup name, the catalyst TableAlreadyExistsException is translated to AlreadyExistsException with this message, aborting the migration before any destructive change.
Solutions
- Drop or rename the existing backup table before re-running the migration
- Choose a different source table name or ensure the backup suffix doesn't collide
- If the backup table is from an earlier failed run, restore it or delete it after inspection
Example fix
// before
spark.sql("MIGRATE TO catalog.db.my_table"); // db.my_table_BACKUP_<ts> exists
// after
spark.sql("DROP TABLE IF EXISTS catalog.db.my_table_BACKUP_<old_ts>");
spark.sql("MIGRATE TO catalog.db.my_table"); Defensive patterns
Strategy: validation
Validate before calling
String backup = sourceIdent.name() + "_BACKUP_" + ...; // compute backup ident
if (catalog.tableExists(backupIdent)) { /* drop or pick new backup name first */ } Try / catch
try { action.execute(); } catch (AlreadyExistsException e) { /* drop stale backup table, then retry */ } Prevention
- Clean up backup tables from previously failed migrations
- Check for tables matching the backup naming pattern before migrating
- Don't name production tables with the backup suffix pattern
When it happens
Trigger: Running migrateTable when the computed backup identifier (source name suffixed with BACKUP_TABLE_SUFFIX, e.g. 'table_BACKUP_') already exists in the destination catalog, often from a prior failed/interrupted migration.
Common situations: Re-running a migration that previously failed midway and left the backup table; a pre-existing user table colliding with the backup naming pattern.
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
- ALTER VIEW AS is not supported. Use CREATE OR REPLACE VIEW…
- AS OF is not supported for changelogs
- Cannot add partition field to non-Iceberg table: $table
- Cannot add partition field to non-Iceberg table: $table
- Cannot apply unknown table change:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/9a330f2a852c9c3a.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/MigrateTableSparkAction.java:242
Preconditions.checkArgument(
catalog instanceof SparkSessionCatalog,
"Cannot migrate a table from a non-Iceberg Spark Session Catalog. Found %s of class %s as the source catalog.",
catalog.name(),
catalog.getClass().getName());
return (TableCatalog) catalog;
}
private void renameAndBackupSourceTable() {
try {
LOG.info("Renaming {} as {} for backup", sourceTableIdent(), backupIdent);
destCatalog().renameTable(sourceTableIdent(), backupIdent);
} catch (org.apache.spark.sql.catalyst.analysis.NoSuchTableException e) {
throw new NoSuchTableException("Cannot find source table %s", sourceTableIdent());
} catch (org.apache.spark.sql.catalyst.analysis.TableAlreadyExistsException e) {
throw new AlreadyExistsException(
"Cannot rename %s as %s for backup. The backup table already exists.",
sourceTableIdent(), backupIdent);
}
}
private void restoreSourceTable() {
try {
LOG.info("Restoring {} from {}", sourceTableIdent(), backupIdent);
destCatalog().renameTable(backupIdent, sourceTableIdent());
} catch (org.apache.spark.sql.catalyst.analysis.NoSuchTableException e) {
LOG.error(
"Cannot restore the original table, the backup table {} cannot be found", backupIdent, e);
} catch (org.apache.spark.sql.catalyst.analysis.TableAlreadyExistsException e) {
LOG.error(
"Cannot restore the original table, a table with the original name exists. "
+ "Use the backup table {} to restore the original table manually.",View on GitHub (pinned to 86d9c8fc54)