CHECK constraint failed
A row you tried to write violates a CHECK constraint's rule — the constraint is doing exactly what it was declared to do. The fix is deciding whether the data or the rule is wrong.
- SQLite:
CHECK constraint failed: amount >= 0 - PostgreSQL:
ERROR: new row for relation "orders" violates check constraint "orders_amount_check" DETAIL: Failing row contains (1, -50, ...). - MySQL (8.0.16+; earlier versions silently ignore
CHECK):Check constraint 'orders_chk_1' is violated. - SQL Server:
The INSERT statement conflicted with the CHECK constraint "CK_orders_amount". The conflict occurred in database "...", table "dbo.orders", column 'amount'.
Loading editor…
The cause
A CHECK constraint is a boolean expression attached to a column or table
that every row has to satisfy. Unlike NOT NULL, UNIQUE, and foreign
keys — which all enforce a specific, narrow shape — CHECK can express
almost any rule: a range, a set of allowed values, a relationship between
two columns in the same row. It's doing its job here; -50 genuinely
fails amount >= 0.
Two legitimate responses, and they're opposites
The data is wrong — this is the common case, and the fix is upstream:
find why your application produced a negative amount and fix that, the
same way you would for a NOT NULL or foreign key violation.
The constraint is wrong, or was true when written and isn't anymore — requirements change. If negative amounts are now a legitimate case (a refund represented as a negative order, say), the constraint needs updating, not the data forced around it:
-- PostgreSQL / SQLite: drop and re-add
ALTER TABLE orders DROP CONSTRAINT orders_amount_check;
ALTER TABLE orders ADD CONSTRAINT orders_amount_check CHECK (amount >= -10000);
-- MySQL / SQL Server: broadly the same shape, constraint names required
ALTER TABLE orders DROP CONSTRAINT orders_amount_check;
ALTER TABLE orders ADD CONSTRAINT orders_amount_check CHECK (amount >= -10000);A row that respects the (corrected) rule succeeds normally:
Loading editor…
Multi-column CHECK constraints fail the same way, with a less obvious cause
A CHECK isn't limited to one column — it can compare several, which
means the failing value in the error message might not be the column that
actually violates the rule:
Loading editor…
When a CHECK failure doesn't make sense looking only at the column
named in the error, read the full constraint definition — the rule may
span more than one column.
- Foreign key constraint fails — the other constraint family, enforcing a relationship instead of a rule.
- Duplicate key / unique constraint violation — enforcing uniqueness instead of a boolean rule.
- INSERT — where these constraints get checked.