Independent technical referenceOfficial site
  • Software and digital services
  • Databases

23514

PostgreSQL 23514 check_violation: row fails CHECK expression

Verified with sources2 sourcesReviewed Oct 19, 2026
Technician coming? See the 2 steps they must show you
Trace

Risk 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.

  1. 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.

  2. 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.

  1. Read the Constraint, Schema, Table, and Data type fields from ErrorResponse

    No special tools

    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

  2. Extract the exact boolean expression with pg_get_constraintdef on pg_constraint

    Tools required

    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

  3. Test the bound row values against TRUE, FALSE, and NULL semantics of CHECK

    Tools required

    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. 1

    PostgreSQL 18 Appendix A: Error Codes

    PostgreSQL Global Development Group · 2026 · official_doc

  2. 2

    PostgreSQL constraints

    PostgreSQL Global Development Group · 2026 · official_doc

Sources: PostgreSQL 18 Appendix A: Error Codes · PostgreSQL constraintsreviewed 2026-10-19 · verified

Was this entry useful?