PostgreSQL error 23505 (Unique Violation) explained: what it means, why it happens, and how to fix it — with copy-paste code examples.
Inspect the error detail for the exact constraint and conflicting key value. If that does not apply, decide between rejecting, updating, or skipping the duplicate row — the full checklist is below.
SQLSTATE: 23505
Official name: Unique Violation
Service: PostgreSQL
A unique constraint or exclusion constraint was violated while inserting or updating a row, because a conflicting row already exists.
INSERT INTO users (email, name)
VALUES ('a@b.com', 'Ada')
ON CONFLICT (email)
DO UPDATE SET name = EXCLUDED.name
RETURNING id;
ON CONFLICT converts a would-be unique violation into an atomic update, avoiding error 23505 entirely.
SELECT setval('users_id_seq', COALESCE(MAX(id), 0) + 1, false)
FROM users;
When a manually-set id exceeds the sequence value, the next auto-generated id collides; reset the sequence above MAX(id).
Catch PrismaClientKnownRequestError with code P2002 (maps to SQLSTATE 23505) and return a clean duplicate response instead of crashing.
try {
await prisma.user.create({ data: { email } });
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === 'P2002') {
return { error: 'Email already exists' };
}
throw e;
}
Use get_or_create() or catch IntegrityError (django.db) to handle duplicates at the ORM layer.
from django.db import IntegrityError
try:
obj = MyModel.objects.create(email=email)
except IntegrityError:
obj = MyModel.objects.get(email=email)
Catch sqlalchemy.exc.IntegrityError, optionally with savepoint rollback before retrying.
from sqlalchemy.exc import IntegrityError
try:
session.add(User(email=email))
session.commit()
except IntegrityError:
session.rollback()
Use upsert() with onConflict to let Postgres handle duplicates server-side instead of returning 23505.
const { error } = await supabase
.from('users')
.upsert({ email }, { onConflict: 'email' })
Most often this happens when inserting a duplicate value into a column with a UNIQUE constraint, or when using INSERT ... ON CONFLICT DO NOTHING but the conflict clause omits the right column.
Inspect the error detail for the exact constraint and conflicting key value.
This page documents fixes for: prisma, django, sqlalchemy, supabase.
Recommendations are editorial — DB Error Reference takes no payment or affiliate fees for tool listings.
This page is based on the official PostgreSQL documentation linked below and adds practical troubleshooting guidance on top.