ERROR 1050 (42S01): Table '<table_name>' already exists is raised when a CREATE TABLE statement targets a table name that already exists in the current schema. The error symbol is ER_TABLE_EXISTS_ERROR.
Impact
The CREATE TABLE statement fails immediately and no new table is created. In most MySQL storage engines this is a statement-level error and does not roll back the surrounding transaction, but the table you intended to create is simply not there. Any subsequent statements in the same script or migration that depend on the table will also fail.
Developers most commonly encounter this during database migrations, application bootstrapping, or deployment scripts that run CREATE TABLE statements without guarding against pre-existing objects. ORMs like Django, SQLAlchemy, and Hibernate surface this as a native database exception (e.g., django.db.utils.OperationalError, sqlalchemy.exc.OperationalError) with the MySQL error code 1050 in the message.
Common Causes
Running a migration or setup script more than once. A script that creates tables without
IF NOT EXISTSwill fail on the second run because the tables already exist from the first.Parallel or out-of-order deployments. Two application instances or CI jobs running schema migrations simultaneously can both attempt to create the same table, with one succeeding and the other hitting error 1050.
Leftover table from a failed or partial migration. A previous migration created the table but failed before completing, leaving the table in an inconsistent state. Re-running the migration tries to create the table again.
Importing a SQL dump into a non-empty database. Restoring a
mysqldumpfile onto a schema that already contains tables of the same names will raise this error for every conflicting table unless the dump was generated with--add-drop-table.Name collisions in multi-tenant schemas. Dynamic table creation (e.g., per-tenant tables) that does not check for existence before issuing
CREATE TABLE.Case-sensitivity on case-insensitive filesystems. On Linux with
lower_case_table_names=0,Ordersandordersare distinct. On Windows or macOS withlower_case_table_names=1or2, they resolve to the same object, so creating one after the other raises 1050.
Troubleshooting and Resolution Steps
Confirm the table exists.
SHOW TABLES LIKE 'your_table_name'; -- or SELECT TABLE_NAME, TABLE_SCHEMA, CREATE_TIME FROM information_schema.TABLES WHERE TABLE_NAME = 'your_table_name' AND TABLE_SCHEMA = DATABASE();Use
IF NOT EXISTSto make the statement idempotent. This is the safest fix for migration scripts and application startup code.CREATE TABLE IF NOT EXISTS orders ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, customer_id BIGINT UNSIGNED NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP );With
IF NOT EXISTS, MySQL silently skips the creation and raises a warning (not an error) if the table already exists. Query the warnings withSHOW WARNINGS;.Drop the existing table first if a fresh recreation is intended. Use with caution in production — this permanently removes all data in the table.
DROP TABLE IF EXISTS orders; CREATE TABLE orders ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, customer_id BIGINT UNSIGNED NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP );Inspect the existing table structure before deciding. If the table was left behind by a partial migration, compare its definition to what you expect:
SHOW CREATE TABLE orders\GIf columns are missing or wrong, use
ALTER TABLEto bring it to the desired state rather than dropping and recreating it.For dump restores, regenerate the dump with
--add-drop-table.mysqldump --add-drop-table -u root -p mydb > mydb.sqlThis prepends a
DROP TABLE IF EXISTSbefore eachCREATE TABLE, making the restore idempotent.For migration frameworks, use their built-in idempotency mechanisms instead of raw
CREATE TABLE. For example, Flyway and Liquibase track which migrations have run and skip already-applied ones; Django'smigratecommand does the same via thedjango_migrationstable.
Additional Information
- The SQLSTATE code
42S01belongs to the class42(syntax error or access rule violation) and subclassS01(base table or view already exists), consistent with the SQL standard. - The related error
ERROR 1007 (HY000): Can't create database '<name>'; database existsis the schema-level equivalent of 1050. ERROR 1051 (42S02): Unknown tableis the inverse — raised whenDROP TABLEtargets a table that does not exist. UseDROP TABLE IF EXISTSto avoid it.- On MySQL 8.0+, atomic DDL means that
CREATE TABLEeither fully succeeds or fully rolls back, reducing the chance of partially-created tables that previously could cause confusing 1050 errors on retry. - Some connectors expose the error differently: the MySQL Connector/J throws
com.mysql.cj.jdbc.exceptions.CommunicationsExceptionfor connectivity issues but usesjava.sql.SQLSyntaxErrorExceptionwith vendor error 1050 for this specific case.
Frequently Asked Questions
Does CREATE TABLE IF NOT EXISTS raise an error or a warning?
It raises a warning (not an error). MySQL skips the creation silently and adds a note-level warning. You can inspect it with SHOW WARNINGS;. The statement still returns success (exit code 0), so scripts continue executing normally.
My migration ran successfully once but fails with 1050 on the next deploy. Why?
The most common cause is that your migration tool is not tracking which migrations have already been applied, so it replays them on every deploy. Use a proper migration framework (Flyway, Liquibase, Alembic, Django migrations) or add IF NOT EXISTS to your raw SQL scripts.
Can 1050 occur inside a transaction? Will the transaction roll back?
In MySQL, DDL statements like CREATE TABLE cause an implicit commit of any open transaction before executing. This means the surrounding transaction is already committed when 1050 is raised, so there is nothing to roll back. Plan schema change scripts carefully to avoid leaving the database in a half-migrated state.
Is there a way to rename an existing table to avoid 1050 rather than dropping it? Yes. If you want to preserve the existing table while creating a fresh one, rename the old table first:
RENAME TABLE orders TO orders_backup_20260602;
CREATE TABLE orders ( ... );
This avoids data loss while still letting the CREATE TABLE succeed.