{"record":{"id":"9a330f2a852c9c3a","repo":"apache/iceberg","slug":"cannot-rename-s-as-s-for-backup-the-backup-tabl-9a330f","errorCode":null,"errorMessage":"Cannot rename %s as %s for backup. The backup table already exists.","messagePattern":"Cannot rename (.+?) as (.+?) for backup\\. The backup table already exists\\.","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/MigrateTableSparkAction.java","lineNumber":242,"sourceCode":"    Preconditions.checkArgument(\n        catalog instanceof SparkSessionCatalog,\n        \"Cannot migrate a table from a non-Iceberg Spark Session Catalog. Found %s of class %s as the source catalog.\",\n        catalog.name(),\n        catalog.getClass().getName());\n\n    return (TableCatalog) catalog;\n  }\n\n  private void renameAndBackupSourceTable() {\n    try {\n      LOG.info(\"Renaming {} as {} for backup\", sourceTableIdent(), backupIdent);\n      destCatalog().renameTable(sourceTableIdent(), backupIdent);\n\n    } catch (org.apache.spark.sql.catalyst.analysis.NoSuchTableException e) {\n      throw new NoSuchTableException(\"Cannot find source table %s\", sourceTableIdent());\n\n    } catch (org.apache.spark.sql.catalyst.analysis.TableAlreadyExistsException e) {\n      throw new AlreadyExistsException(\n          \"Cannot rename %s as %s for backup. The backup table already exists.\",\n          sourceTableIdent(), backupIdent);\n    }\n  }\n\n  private void restoreSourceTable() {\n    try {\n      LOG.info(\"Restoring {} from {}\", sourceTableIdent(), backupIdent);\n      destCatalog().renameTable(backupIdent, sourceTableIdent());\n\n    } catch (org.apache.spark.sql.catalyst.analysis.NoSuchTableException e) {\n      LOG.error(\n          \"Cannot restore the original table, the backup table {} cannot be found\", backupIdent, e);\n\n    } catch (org.apache.spark.sql.catalyst.analysis.TableAlreadyExistsException e) {\n      LOG.error(\n          \"Cannot restore the original table, a table with the original name exists. \"\n              + \"Use the backup table {} to restore the original table manually.\",","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/actions/MigrateTableSparkAction.java#L224-L260","documentation":"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.","triggerScenarios":"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.","commonSituations":"Re-running a migration that previously failed midway and left the backup table; a pre-existing user table colliding with the backup naming pattern.","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"],"exampleFix":"// before\nspark.sql(\"MIGRATE TO catalog.db.my_table\"); // db.my_table_BACKUP_<ts> exists\n// after\nspark.sql(\"DROP TABLE IF EXISTS catalog.db.my_table_BACKUP_<old_ts>\");\nspark.sql(\"MIGRATE TO catalog.db.my_table\");","handlingStrategy":"validation","validationCode":"String backup = sourceIdent.name() + \"_BACKUP_\" + ...; // compute backup ident\nif (catalog.tableExists(backupIdent)) { /* drop or pick new backup name first */ }","typeGuard":null,"tryCatchPattern":"try { action.execute(); } catch (AlreadyExistsException e) { /* drop stale backup table, then retry */ }","preventionTips":["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"],"tags":["spark","iceberg","backup-table","name-collision"],"backgroundTag":"file-already-exists","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}