How to Fix MySQL Error 1060: Duplicate Column Name

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

  1. 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.

  2. Multiple ADD COLUMN clauses in one ALTER TABLE that name the same column. A single ALTER TABLE can contain several ADD COLUMN operations; if two of them specify the same name, MySQL raises 1060 for the whole statement.

  3. 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 COLUMN will collide with the existing column. Migration tools that lack idempotency checks are particularly susceptible.

  4. Column name collision after a RENAME COLUMN or application of a CREATE TABLE ... LIKE / CREATE TABLE ... SELECT statement. 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.

  5. Case-insensitive name collision on case-sensitive filesystems. On Linux with the default lower_case_table_names=0 setting, column names are still compared case-insensitively within a table definition, so UserID and userid in the same CREATE TABLE will raise 1060.

Troubleshooting and Resolution Steps

  1. 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.

  2. 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.

  3. Fix a CREATE TABLE with 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)
    );
    
  4. Fix an ALTER TABLE that 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 EXISTS for ADD COLUMN was introduced in MySQL 8.0. On MySQL 5.7, use the information_schema query in step 2 before attempting ALTER TABLE.

  5. Guard migration scripts against re-execution. If you manage migrations manually, wrap ALTER TABLE statements 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;
    
  6. 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 42S21 is 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_mode settings.
  • In Django, this error typically surfaces as django.db.utils.OperationalError: (1060, "Duplicate column name '...'") when running python manage.py migrate after manually editing or squashing migrations.
  • In ActiveRecord (Rails), it appears as Mysql2::Error: Duplicate column name and usually indicates a migration was rolled back manually without updating the schema_migrations table.
  • Related error codes: 1061 (ER_DUP_KEYNAME) is the analogous error for duplicate index names; 1050 (ER_TABLE_EXISTS_ERROR) is raised when CREATE TABLE targets 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.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.