Diagnostic Queries
Symptoms
A row conflicts with an existing row under an EXCLUSION constraint — for example two overlapping time ranges where overlaps are forbidden. PostgreSQL raises SQLSTATE 23P01 (exclusion_violation).
- Common with range types and the
&&(overlaps) operator plus a GiST index. - The DETAIL shows the conflicting key.
- Used to enforce “no double-booking” style rules.
What the server log shows
ERROR: conflicting key value violates exclusion constraint "room_booking_excl"
DETAIL: Key (room, during)=(101, [2026-06-11 09:00,2026-06-11 10:00)) conflicts with existing key (room, during)=(101, [2026-06-11 09:30,2026-06-11 11:00)).
Why PostgreSQL raises this — what the manual says
Section 5.5.6 Exclusion Constraints:
“Exclusion constraints ensure that if any two rows are compared on the specified columns or expressions using the specified operators, at least one of these operator comparisons will return false or null.”
An exclusion constraint is enforced by an index (usually GiST). On insert/update PostgreSQL probes the index for any existing row whose values, compared with the configured operators, do not satisfy the exclusion rule; a conflict raises 23P01.
Common causes
- Inserting an overlapping range (booking, schedule, IP range).
- Concurrent inserts that both pass application checks but overlap.
- Wrong range bounds (inclusive vs exclusive) producing unexpected overlap.
How to fix it
- Adjust the new row so it does not overlap (change the range/key).
- Query for conflicts before inserting, or retry on 23P01.
- Verify your range inclusivity (
[)vs[]) matches the intended semantics.
Related & next steps
Reference: PostgreSQL 18 Section 5.5 “Constraints”.
Thanks — noted. This helps keep the database accurate.