ERROR 1060 (42S21): Duplicate column name '<column>' is raised when a CREATE TABLE or ALTER TABLE statement attempts to define or add a column whose name already exists in the table. The error symbol is ER_DUP_FIELDNAME.
Impact
This is a DDL-time error — MySQL rejects the statement before any data is written. The table is not created (for CREATE TABLE) or not modified (for ALTER TABLE), and the operation is rolled back entirely. No partial changes are made.
Developers typically encounter this error when writing migration scripts, generating schema definitions programmatically, or combining multiple ADD COLUMN clauses in a single ALTER TABLE. ORMs such as Django, ActiveRecord, and Hibernate can trigger it when auto-generated migrations are applied out of order or when migration history has been tampered with. The error message includes the exact column name that is duplicated, which makes it straightforward to locate the problem.
Common Causes
Listing the same column twice in
CREATE TABLE. This is the most common cause: a column name appears in two separate column definitions, either through a copy-paste mistake or a merge conflict in a migration file.Multiple
ADD COLUMNclauses in oneALTER TABLEthat name the same column. A singleALTER TABLEcan contain severalADD COLUMNoperations; if two of them specify the same name, MySQL raises 1060 for the whole statement.Running a migration that adds a column that already exists. If a migration is executed twice, or if the schema has drifted from what the migration tool expects, an
ADD COLUMNwill collide with the existing column. Migration tools that lack idempotency checks are particularly susceptible.Column name collision after a
RENAME COLUMNor application of aCREATE TABLE ... LIKE/CREATE TABLE ... SELECTstatement. When generating a new table from an existing one while also appending extra columns, the selected column names may clash with the explicitly listed columns.Case-insensitive name collision on case-sensitive filesystems. On Linux with the default
lower_case_table_names=0setting, column names are still compared case-insensitively within a table definition, soUserIDanduseridin the sameCREATE TABLEwill raise 1060.
Troubleshooting and Resolution Steps
Read the error message carefully. MySQL tells you the exact duplicate column name:
ERROR 1060 (42S21): Duplicate column name 'email'Search your DDL statement for every occurrence of that name.
Inspect the table's current structure before running
ALTER TABLE.DESCRIBE users; -- or SHOW COLUMNS FROM users; -- or SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'users' ORDER BY ORDINAL_POSITION;If the column already exists, decide whether to skip the
ADD COLUMN, modify the column instead (MODIFY COLUMN/CHANGE COLUMN), or rename the existing column first.Fix a
CREATE TABLEwith duplicate columns by removing the extra definition:-- Broken: 'email' appears twice CREATE TABLE users ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, email VARCHAR(255) NOT NULL, name VARCHAR(100), email VARCHAR(255) -- duplicate! ); -- Fixed CREATE TABLE users ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, email VARCHAR(255) NOT NULL, name VARCHAR(100) );Fix an
ALTER TABLEthat adds the same column twice, or skip adding a column that already exists:-- Broken ALTER TABLE orders ADD COLUMN status VARCHAR(20), ADD COLUMN status VARCHAR(20); -- duplicate! -- Fixed: remove the duplicate clause ALTER TABLE orders ADD COLUMN status VARCHAR(20); -- Safe pattern if the column may or may not already exist (MySQL 8.0.29+) ALTER TABLE orders ADD COLUMN IF NOT EXISTS status VARCHAR(20);Note:
IF NOT EXISTSforADD COLUMNwas introduced in MySQL 8.0. On MySQL 5.7, use theinformation_schemaquery in step 2 before attemptingALTER TABLE.Guard migration scripts against re-execution. If you manage migrations manually, wrap
ALTER TABLEstatements in a conditional:SET @col_exists = ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'orders' AND COLUMN_NAME = 'status' ); SET @sql = IF(@col_exists = 0, 'ALTER TABLE orders ADD COLUMN status VARCHAR(20)', 'SELECT "Column already exists, skipping"' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;Check for case-insensitive name collisions. Even if the names look different in case, MySQL treats column names as case-insensitive within a table:
-- This raises 1060 even though the case differs CREATE TABLE events ( UserID INT, userid INT -- duplicate! );Rename one of the columns to something semantically distinct.
Additional Information
- The SQLSTATE code
42S21is part of the SQL standard and maps to "column already exists"; some drivers expose it alongside the MySQL-specific 1060 error number. - This error is unrelated to SQL strict mode — it is raised regardless of
sql_modesettings. - In Django, this error typically surfaces as
django.db.utils.OperationalError: (1060, "Duplicate column name '...'")when runningpython manage.py migrateafter manually editing or squashing migrations. - In ActiveRecord (Rails), it appears as
Mysql2::Error: Duplicate column nameand usually indicates a migration was rolled back manually without updating theschema_migrationstable. - Related error codes: 1061 (
ER_DUP_KEYNAME) is the analogous error for duplicate index names; 1050 (ER_TABLE_EXISTS_ERROR) is raised whenCREATE TABLEtargets an existing table name.
Frequently Asked Questions
Why does MySQL raise 1060 even though I'm using different capitalization for the two column names?
MySQL column names are case-insensitive, so Email, email, and EMAIL are treated as the same name within a table definition. Rename one of the columns to a truly distinct name.
I only have one ADD COLUMN clause in my migration — why am I still getting 1060?
The column you are trying to add already exists in the table. This often happens when a migration is run more than once, or when the schema was modified outside of the migration tool. Use SHOW COLUMNS FROM <table> to confirm the column's presence, and either skip the migration or use ADD COLUMN IF NOT EXISTS (MySQL 8.0+).
Does ALTER TABLE ... ADD COLUMN IF NOT EXISTS work in MySQL 5.7?
No. IF NOT EXISTS for ADD COLUMN was introduced in MySQL 8.0. On 5.7, query information_schema.COLUMNS before issuing the ALTER TABLE, or catch the 1060 error in your application code and treat it as a no-op.
Can this error occur in a stored procedure or migration that worked before?
Yes. If the stored procedure runs ALTER TABLE and the underlying table has already been modified (e.g., by another migration or a manual schema change), the column may already exist. Use the information_schema guard pattern above to make the procedure idempotent.