SQLSTATE[42S21]: Column already exists

Database Migration Error: Column Already Exists – Quick Fix

Database Errors Intermediate 👁 8 views 📅 Jun 27, 2026

Tired of that migration fail? Here's how to skip the duplicate column and move on. No fluff, just the fix.

Why Your Migration Died

You ran a migration and got hit with something like SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'status'. That's annoying. I had a client last month whose entire deploy pipeline stopped because of this – wasted 2 hours before calling me. The root cause is simple: the column already exists in the table, but your migration code tries to add it again. This happens when you manually added a column in the database (maybe via a hotfix) and then later ran a migration that tries to add the same column. Or someone ran a migration partially, then rolled back incorrectly.

The Fastest Fix: Modify Your Migration to Check First

Don't delete the column and re-run the migration – that's risky. Instead, update the migration file to check if the column already exists before adding it. In Laravel (or any schema builder), do this:

if (!Schema::hasColumn('your_table_name', 'status')) {
    Schema::table('your_table_name', function (Blueprint $table) {
        $table->string('status')->default('pending');
    });
}

This way, if the column's already there, your migration just skips that part. Runs clean every time. For non-Laravel (like raw SQL), wrap it in a check like:

SELECT COUNT(*) FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'your_table' AND COLUMN_NAME = 'status';

If it returns 0, then run the ALTER TABLE. Otherwise, skip.

Why This Works

Migrations are supposed to be idempotent – meaning you can run them multiple times without breaking anything. But many frameworks don't enforce that. The column already exists error happens because the schema engine tries to add a column that's physically there. By adding a check, you make the migration safe to run again. This is especially critical in CI/CD where migrations run automatically.

Less Common Variations

Sometimes the error looks different – Duplicate column name in MySQL, column "x" of relation "y" already exists in PostgreSQL. Same fix applies. Here's when it gets tricky:

  • Migration halfway through a batch: If you're using Doctrine or Flyway and the migration failed, it might have partially applied. The column's there but the migration thinks it's not. Solution: Check the migration's version table and manually mark it as run, or run the check fix above and then mark it complete.
  • Multiple migrations with same column: I've seen devs accidentally create two migrations that both add the same column. Fix: Remove the duplicate migration file and run migrate:refresh if safe, or just use the check fix on both.
  • Shared database across environments: If staging and production have different schema states, the migration might add the column in one but error in another. The check fix solves it universally.

Prevention – Keep It From Happening Again

Here's what I tell every client:

  1. Never add columns manually in production – always use a migration. If you need a hotfix, write the migration and run it, don't use phpMyAdmin or raw SQL.
  2. Use idempotent migrations – always wrap adds, drops, and changes in Schema::hasColumn or Schema::hasTable checks. It's two extra lines and saves hours.
  3. Test migrations on a clone of production – before deploying, run them on a copy of the live database. Catches column conflicts early.
  4. Version your schema – use tools like Doctrine Migrations or Laravel's built-in system. Never rely on manual SQL scripts that can get out of sync.

Do that, and you won't see this error again. I promise.

Was this solution helpful?