MySQL Error 1062: Duplicate Entry

MySQL error 1062 (Duplicate Entry) explained: what it means, why it happens, and how to fix it — with copy-paste code examples.

MySQL Error Code 1062 MySQL Last verified 2026-08-19

Quick Answer

Read the full message: it names the duplicate value and the key ('Duplicate entry X for key Y'). If that does not apply, for idempotent inserts use `INSERT ... ON DUPLICATE KEY UPDATE col=VALUES(col)` or `INSERT IGNORE` — the full checklist is below.

Error Code

MySQL Error Code: 1062
Official name: Duplicate Entry
System name: Duplicate entry
Service: MySQL

What does this error mean?

Duplicate entry '%s' for key %s

Exact Error Messages

You may see this error reported as one of the following messages:

Common Causes

How to Fix

  1. Read the full message: it names the duplicate value and the key ('Duplicate entry X for key Y')
  2. For idempotent inserts use `INSERT ... ON DUPLICATE KEY UPDATE col=VALUES(col)` or `INSERT IGNORE`
  3. Use `SELECT ... FOR UPDATE` inside a transaction for check-then-insert flows where the key is business-critical
  4. Find and remove existing duplicates with a GROUP BY ... HAVING COUNT(*) > 1 query before retrying
  5. Surface a clear 409-style error to API callers instead of leaking the raw duplicate message

Example Scenario

A users table has UNIQUE KEY users_email (email). A retry loop re-sends a signup after a network timeout — the first INSERT already succeeded. MySQL returns ERROR 1062 (23000): Duplicate entry 'john@example.com' for key 'users.email'. The key name in the message tells you exactly which unique index fired; PRIMARY fires the same way when a row with that id already exists.

Diagnostic Commands

Run these to confirm the cause before applying a fix — each command answers a specific question.

Which unique indexes does this table have? sql
SHOW CREATE TABLE users;

The UNIQUE KEY / PRIMARY KEY lines list every index that can raise 1062 — match the key name from the error message.

Which duplicate rows already exist? sql
SELECT email, COUNT(*) c FROM users
GROUP BY email HAVING c > 1;

Existing duplicates mean the unique index was added later (or is being added); clean them before the constraint can hold.

Decision Guide

Is the duplicate insert intentional (retry / upsert)?
├─ YES → INSERT ... ON DUPLICATE KEY UPDATE name = VALUES(name)
│        or INSERT IGNORE when you only need 'already there' semantics
└─ NO  → find the conflicting row
          ├─ row is valid → reject/fix the application input ('email taken')
          └─ row is stale → delete or merge, then retry

Duplicate on AUTO_INCREMENT id?
└─ explicit id insert bypassed the counter →
   bump it: ALTER TABLE users AUTO_INCREMENT = <MAX(id)+1>;

Code Examples

Idempotent upsert sql
INSERT INTO users (email, name)
VALUES ('ada@example.com', 'Ada')
ON DUPLICATE KEY UPDATE
  name = VALUES(name);

When the unique key already exists, the UPDATE branch runs instead of failing with 1062.

Find the duplicates sql
SELECT email, COUNT(*)
FROM users
GROUP BY email
HAVING COUNT(*) > 1;

Locates existing rows that share a unique value so you can clean them before retrying.

Framework-Specific Fixes

nodejs-mysql2

Catch the driver error, check err.code === 'ER_DUP_ENTRY', and map it to HTTP 409 with the duplicate key name.

try {
  await pool.query(
    'INSERT INTO users (email) VALUES (?) ON DUPLICATE KEY UPDATE email = email',
    [email],
  )
} catch (err) {
  if (err.code === 'ER_DUP_ENTRY') return res.status(409).json({ error: 'Email already taken' })
  throw err
}

python-sqlalchemy

Let IntegrityError propagate to a handler that inspects the underlying driver code 1062.

from sqlalchemy.exc import IntegrityError
try:
    session.add(user)
    session.commit()
except IntegrityError as e:
    if e.orig.args[0] == 1062:
        raise DuplicateUser(email) from e
    raise

php-pdo

Check errorInfo[1] === 1062 after catching PDOException and return 409.

try {
  $pdo->exec("INSERT INTO users (email) VALUES ('$email')");
} catch (PDOException $e) {
  if ($e->errorInfo[1] === 1062) { http_response_code(409); exit('email exists'); }
  throw $e;
}

You Might Also Like

Frequently Asked Questions

Why am I seeing MySQL error 1062?

Most often this happens when inserting or updating a row whose value collides with an existing unique key (email, username, order number, external id), or when retrying an insert after a timeout or partial failure, so the row was actually created but the retry hits the unique index.

How do I fix MySQL error 1062?

Read the full message: it names the duplicate value and the key ('Duplicate entry X for key Y').

Which frameworks have documented fixes for error 1062?

This page documents fixes for: nodejs-mysql2, python-sqlalchemy, php-pdo.

Official Sources

This page is based on the official MySQL documentation linked below and adds practical troubleshooting guidance on top.