PostgreSQL error 23503 (Foreign Key Violation) explained: what it means, why it happens, and how to fix it — with copy-paste code examples.
Read the error detail for the constraint name and the offending key value. If that does not apply, verify the referenced parent row exists before inserting the child — the full checklist is below.
SQLSTATE: 23503
Official name: Foreign Key Violation
Service: PostgreSQL
A foreign key constraint was violated because a referenced row does not exist, or an operation would orphan a referenced row.
SELECT conname, conrelid::regclass AS table_name,
pg_get_constraintdef(oid) AS definition
FROM pg_constraint
WHERE contype = 'f';
List all FK constraints and their exact definitions so you can see which columns and ON DELETE actions are in play.
ALTER TABLE orders
ADD CONSTRAINT orders_customer_id_fkey
FOREIGN KEY (customer_id) REFERENCES customers(id)
DEFERRABLE INITIALLY DEFERRED;
Deferrable constraints are checked at commit, allowing you to insert child rows before parents within a transaction.
Create parent objects before children, or use bulk_create with explicit ordering; wrap in a transaction.
with transaction.atomic():
parent = Parent.objects.create(name='x')
Child.objects.create(parent=parent)
Flush parent rows before children so ORM assigns generated FK ids before the child insert fires.
parent = Parent(name='x')
session.add(parent)
session.flush() # assigns parent.id
session.add(Child(parent_id=parent.id))
Insert parent records first via the dashboard or API, then reference their id in the child insert.
const { data: parent } = await supabase
.from('parents').insert({ name: 'x' }).select().single();
await supabase.from('children').insert({ parent_id: parent.id });
Most often this happens when inserting a child row whose parent id does not exist, or when deleting or updating a parent row that is still referenced by child rows without ON DELETE/UPDATE CASCADE.
Read the error detail for the constraint name and the offending key value.
This page documents fixes for: 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.