Quick answer
Run SHOW ENGINE INNODB STATUS\G to see the exact key conflict, then delete or update the duplicate row, or use INSERT IGNORE / ON DUPLICATE KEY UPDATE to bypass it.
Why this happens
I've seen this error more times than I can count—usually during a bulk import or when a cron job tries to re-insert data that already exists. MySQL error 1062 shows up as something like: Duplicate entry '12345' for key 'PRIMARY'. That '12345' is the offending key value. The real trigger is often a race condition in concurrent inserts, a failed previous insert that left a partial row, or a script that doesn't check for existing records before inserting. It's not a bug—it's MySQL doing its job of protecting your unique constraints. But it can stop a whole batch job cold.
Fix steps
- Identify the conflict
Run this to get the exact key and table:
Look for theSHOW ENGINE INNODB STATUS\GLATEST DETECTED ERRORsection. It'll show the table name and the duplicate value. - Query the table for the duplicate
Replaceyour_tableandprimary_key_columnwith what you found:
This returns the existing row. Decide if you want to delete it, update it, or skip the insert.SELECT * FROM your_table WHERE primary_key_column = '12345'; - Fix the cause
- Delete the duplicate:
DELETE FROM your_table WHERE primary_key_column = '12345'; - Update it:
UPDATE your_table SET other_column = 'new_value' WHERE primary_key_column = '12345'; - Skip duplicates in your insert: Use
INSERT IGNORE INTO your_table ...— this suppresses the error and just skips rows that would cause duplicates. Or useINSERT INTO your_table ... ON DUPLICATE KEY UPDATE column1 = VALUES(column1);which updates the existing row instead.
- Delete the duplicate:
- For bulk imports from CSV
UseLOAD DATA INFILEwith theIGNOREoption:LOAD DATA INFILE '/path/to/file.csv' IGNORE INTO TABLE your_table FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
Alternative fixes if the main one fails
- Check for triggers: A trigger on the table might be inserting into another table that has a unique constraint. Disable it temporarily with
DISABLE TRIGGER trigger_name;and test. - Look at foreign keys: If the table has a foreign key pointing to the primary key, deleting the parent row might cascade and fix it. But be careful—this can blow away related data. Check with
SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = 'your_table'; - Temporarily disable unique checks: For a one-time fix in a dev environment, run
SET UNIQUE_CHECKS = 0;before the insert. Never do this in production—it can corrupt your data. - Repair the table: If the index itself is corrupted (rare but possible after a crash), run
REPAIR TABLE your_table;— this rebuilds indexes and might clear phantom duplicates.
Prevention tip
Don't let duplicates creep in. Use INSERT ... ON DUPLICATE KEY UPDATE in your application code—it's your best friend. Also, add a UNIQUE constraint on business keys (like email or order number) so MySQL catches it at the database level, not the app. And for batch jobs, always wrap inserts in a transaction with a ROLLBACK on error so you don't end up with partial data.