- Software and digital services
- Databases
23514
PostgreSQL 23514 check_violation: row fails CHECK expression
Evidence linked to this decision
View source: PostgreSQL 18 Appendix A: Error CodesRisk level
Medium
Proceed carefully and stop if the check is unclear.
Urgency
Medium
Quick answer
PostgreSQL 23514 (check_violation) means a new or updated row made a table or domain CHECK constraint evaluate to FALSE. Check the Constraint and Table fields in the error, inspect the boolean expression with `pg_get_constraintdef`, and correct the input values before retrying.
Safety first
Stop and check this first
- Never write `CHECK` constraints that reference other table rows or mutable functions, and never mark a constraint `NOT ENFORCED` just to bypass 23514; cross-row or mutable `CHECK` rules can cause a later database dump and restore to fail.
- Do not attempt to include unredacted row payloads from `Detail` messages in bug reports or support tickets when those columns contain personal or financial data.
Safe checks you can perform
- Read the Constraint, Schema, Table, and Data type fields from ErrorResponse
- Extract the exact boolean expression with pg_get_constraintdef on pg_constraint
- Test the bound row values against TRUE, FALSE, and NULL semantics of CHECK
Leave these tasks to a qualified professional
- Do not attempt this professional task: Validate and correct input values or column defaults before executing the write
- Do not attempt this professional task: Drop, update, and re-add the CHECK constraint when a rule or function changes
What a technician must be able to justify
Technician visit
These are the steps they must carry out and show you. Tick them as they work: if steps are skipped, do not accept a part swap.
These are not instructions for opening or handling the equipment yourself. They are the checks that should support a technical conclusion.
Validate and correct input values or column defaults before executing the write
What they doHave your application developer enforce the same boundary rules in client/API validation and ensure that any column `DEFAULT` expression also satisfies the `CHECK` condition before issuing `INSERT` or `UPDATE`.
They must show youthe `pg_get_constraintdef` expression and a test transaction demonstrating that corrected inputs evaluate to `TRUE` and commit cleanly.
In writingthe constraint name (`n`), the exact `CHECK` expression, and the input validation rule added to the application.
Drop, update, and re-add the CHECK constraint when a rule or function changes
What they doWhen a business rule or a user-defined function referenced by a `CHECK` constraint must change, have the DBA take a backup, drop the constraint with `ALTER TABLE`, update the function or rule, and re-add the `CHECK` constraint so PostgreSQL rechecks all existing table rows.
They must show youthe updated `pg_constraint` row with `convalidated = true` and `conenforced = true` plus the `pg_get_constraintdef` output.
In writingthe `ALTER TABLE` migration script, confirmation that all existing rows passed validation, and the backup reference.
Before accepting a part or repair
Nothing has been shown yet. Do not accept a part swap based on the code alone.
Follow these steps
Note: Follow the documented order. An error code identifies the affected system, but it does not prove by itself which part has failed.
Read the Constraint, Schema, Table, and Data type fields from ErrorResponse
- Who:
- You or your developer inspect the structured ErrorResponse fields returned for SQLSTATE 23514.
- How:
- Record protocol fields `n` (Constraint name), `s` (Schema name), `t` (Table name), `d` (Data type name, when a domain constraint failed), and `D` (Detail) using `\set VERBOSITY verbose` in `psql` or your driver's error properties.
- Result that matters:
- PostgreSQL supplies the exact constraint name in field `n` and either the table in `t` or the domain in `d`.
- If `n` and `t` are populated, that confirms a table or column `CHECK` constraint on table `t` evaluated to `FALSE` for the proposed row.
- If `d` is populated alongside `n`, that confirms a domain `CHECK` constraint rejected a value cast or assigned to that domain type.
- Evidence to keep:
- Save the exact `n`, `s`, `t`, `d`, and redacted `D` values from the error report.
Evidence: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL error and notice fields · PostgreSQL pg_constraint catalog
Extract the exact boolean expression with pg_get_constraintdef on pg_constraint
- Who:
- Your developer or DBA queries `pg_constraint` in a read-only session.
- How:
- Run `SELECT conname, conrelid::regclass AS table_name, contypid::regtype AS domain_name, connoinherit, convalidated, pg_get_constraintdef(oid, true) AS definition FROM pg_constraint WHERE conname = '<constraint_name>' AND contype = 'c';`.
- Result that matters:
- Table 52.13 recommends using `pg_get_constraintdef()` to extract the definition of a check constraint (`contype = 'c'`).
- If the decompiled `CHECK (...)` expression compares multiple columns (such as `CHECK (price > discounted_price)`), that confirms you must inspect the relationship between all referenced columns in the row, not a single field in isolation.
- If the expression calls a user-defined function, that points to testing that function's output on the rejected row values to see whether its logic changed.
- Evidence to keep:
- Keep the full `pg_get_constraintdef` string and the `table_name` or `domain_name` from `pg_constraint`.
Perform read-only `SELECT` queries only; issue `ROLLBACK;` first if your client session is still inside the aborted transaction.
Evidence: PostgreSQL constraints · PostgreSQL pg_constraint catalog · PostgreSQL 18 system information functions
Test the bound row values against TRUE, FALSE, and NULL semantics of CHECK
- Who:
- Your developer evaluates the exact bound values from the failed `INSERT` or `UPDATE` against the decompiled expression in a read-only `SELECT`.
- How:
- Run `SELECT (<check_expression>) IS FALSE AS fails_check` using the proposed column values (and any omitted columns' `DEFAULT` values) as constants.
- Result that matters:
- A `CHECK` constraint is satisfied if its expression evaluates to `TRUE` or `NULL` (`UNKNOWN`), and fails only when the result is `FALSE`.
- If the test `SELECT` returns `true` for `IS FALSE`, that confirms which specific column values or default values violated the expression.
- If the values you thought the app sent do not make the expression `FALSE`, that points to a `BEFORE` trigger or default expression modifying the row before constraint evaluation.
- Evidence to keep:
- Record the read-only test `SELECT` expression and the sanitized input values that produced `FALSE`.
Do not test with live `INSERT` or `UPDATE` statements on production tables; evaluate the boolean expression in a read-only `SELECT`.
Evidence: PostgreSQL constraints · PostgreSQL 18 CREATE TABLE
Still not solved
If the error persists, stop here. See what the technician must do and show you.
Virtual technician
Does 23514 still appear after these checks?
This guided flow uses the exact code and your answers to choose a test, an expected result and the next branch.
Where this code applies
A code is meaningful only inside the right product and version context.
Primary scope
- System
- Software and digital services
- Brand
- PostgreSQL
- Product type
- Databases
Known code variants
- check_violation
- PostgreSQL 23514
- SQLSTATE 23514
What it means
Appendix A of the PostgreSQL documentation assigns SQLSTATE 23514 to `check_violation` in Class 23 (Integrity Constraint Violation). A `CHECK` constraint requires column values in a new or updated table row (or domain value) to satisfy a boolean expression. In PostgreSQL, a `CHECK` expression succeeds when it evaluates to `TRUE` or `UNKNOWN` (null); an error is raised only when it evaluates to `FALSE`, leaving the table unchanged. `CHECK` constraints are checked immediately on row write in alphabetical order after `NOT NULL` checks and are never deferrable. The code alone does not prove whether a single column, a multi-column check, a default or a modified function caused the `FALSE` result.
Warnings and stop conditions
- Mediumsource verified
Never write `CHECK` constraints that reference other table rows or mutable functions, and never mark a constraint `NOT ENFORCED` just to bypass 23514; cross-row or mutable `CHECK` rules can cause a later database dump and restore to fail.
Evidence: PostgreSQL constraints · PostgreSQL 18 CREATE TABLE
- Lowsource verified
Do not attempt to include unredacted row payloads from `Detail` messages in bug reports or support tickets when those columns contain personal or financial data.
Evidence: PostgreSQL error and notice fields · PostgreSQL bug reporting guidelines
Symptoms and causes
Probable causes · in order
- A single-column or multi-column value in the INSERT, UPDATE, or DEFAULT evaluated to FALSECommon
CREATE TABLE and Section 5.5.1 state that should any row of an insert or update operation produce a FALSE result for a CHECK expression (including values from a default definition), an error exception is raised.
Evidence: PostgreSQL constraints · PostgreSQL 18 CREATE TABLE
- A domain CHECK constraint or inherited parent CHECK constraint rejected the valuePossible
The pg_constraint catalog stores CHECK constraints on domains (`contypid`) as well as tables (`conrelid`), and child tables or partitions inherit parent CHECK constraints unless marked NO INHERIT.
Evidence: PostgreSQL pg_constraint catalog · PostgreSQL 18 CREATE TABLE
- A user-defined function referenced inside a CHECK expression changed behavior, failing on row writes or pg_dump restoreLess common
Section 5.5.1 warns that PostgreSQL assumes CHECK conditions are immutable; if a user-defined function used in a CHECK expression is modified later, existing or restored rows that now return FALSE will fail during updates or a database dump and restore.
Evidence: PostgreSQL constraints
Sources and technical references
- 1
PostgreSQL 18 Appendix A: Error Codes
PostgreSQL Global Development Group · 2026 · official_doc
- 2
PostgreSQL Global Development Group · 2026 · official_doc
Was this entry useful?