PostgreSQL: ERROR: duplicate key value violates unique constraint
An INSERT/UPDATE would create a duplicate in a UNIQUE or PRIMARY KEY column — or the id sequence is behind the existing data.
Seen on:
PostgreSQL
Meaning
The DETAIL line names the key: Key (email)=(a@b.com) already exists. If the key is id and you never set ids manually, the sequence is out of sync — very common after importing data or restoring a dump with explicit ids.
Common causes
- Inserting a value that already exists (double submit, retry, race)
- Sequence behind max(id) after a manual import/restore (
Key (id)=(5) already exists) - Unique index on a column you didn’t expect (case-insensitive email index)
- Upsert logic that checks-then-inserts without a transaction
⚡ Quick fix
- Read the DETAIL line to see which key and value collided
- For id collisions, resync the sequence (below)
- Use
INSERT … ON CONFLICT … DO UPDATE / DO NOTHINGfor upserts - Catch SQLSTATE 23505 and return a friendly “already exists” error
Detailed fix by platform
PostgreSQL
- Resync an id sequence after imports:sql
SELECT setval(pg_get_serial_sequence('users', 'id'), COALESCE(MAX(id), 1)) FROM users; - Upsert instead of check-then-insert:sql
INSERT INTO users (email, name) VALUES ('a@b.com', 'Asha') ON CONFLICT (email) DO UPDATE SET name = EXCLUDED.name;
How to diagnose
- Key — Which constraint and value (DETAIL line)?
- Sequence — Is it the id? Compare nextval with max(id)
- Concurrency — Two requests inserting the same value?
🧠 Still stuck? Analyze your error
Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.
Was this page helpful?
Report a correction or suggest an improvement
Last updated 2 Oct 2026