Fix “Failing Row Contains” Constraint Errors in SQL
An INSERT, UPDATE, or DELETE broke a rule on the table. The detail line names the row.
The symptom
A database rejects an INSERT, UPDATE, orDELETE and includes a detail line like"Failing row contains (...)". The statement did not quietly skip that row; it failed because the row would break a rule on the table.
The garden_shop practice tables load straight from CSV and carry no constraints of their own, so the bench below declares a small table with three rules on it - a primary key, a unique email, and a check on the plan. Only one of them fires. Read the message to find out which, then switch to the fix.
DuckDB reports this as Constraint Error: Duplicate key "email: ada@example.com" violates unique constraint. - the second row reuses an email the first row already took. Notice what the message gives you: the rule that fired, the column, and the value. It does not print a "Failing row contains" line at all. PostgreSQL, where this page's title phrase comes from, prints both the constraint name and aDETAIL: Failing row contains (...) line showing every value in the rejected row, which is why the phrase became a common thing to search for.
Read the line before the row
The values inside failing row contains are evidence, not the root cause. The real clue is usually the line that names the violated constraint:NOT NULL, CHECK, UNIQUE, primary key, or foreign key.
| Error clue | What it usually means | Go to |
|---|---|---|
not-null constraint | A required column would be NULL. | NOT NULL constraint failed |
check constraint | A row breaks a business rule the table enforces. | CHECK constraint failed |
duplicate key | A unique or primary key value already exists. | Duplicate key violates primary key |
foreign key | A child row points to a missing parent, or a parent has child rows. | Violates foreign key constraint |
generated column | You supplied a value for a column the database computes. | Cannot insert into a generated column |
Debug the rejected row
Turn the values from the error into a small SELECT. Confirm what is missing or duplicated before changing the data.
select customer_id, first_name, last_name, email
from customers
where customer_id = 5;A row comes back, so customer_id 5 is taken: an insert claiming it would collide. Run the same query for a key the error named and gettingnothing back tells you the opposite story - that is the shape of a missing parent rather than a duplicate.
select customer_id
from customers
where customer_id = 42;
-- No rows: an order for customer_id 42 would violate a foreign
-- key that requires customers.customer_id.Fix the data or the rule
Most of the time, the fix is the data: provide the required value, use a valid status, choose a new key, or create the parent row before the child row. Change the table constraint only when the rule itself is wrong.
insert into customers (customer_id, first_name, email)
values (42, 'Ada', 'ada@example.com');The exact phrase "Failing row contains" is common in PostgreSQL error details. Other databases use different words, but the debugging habit is the same: identify the constraint, inspect the row, then fix the data or the rule.
Which engines show you the row
Every engine names the constraint. They differ in whether they hand you the values that were rejected, which is the difference between debugging from the error and going back to the data to find the row yourself.
| Engine | Shows the rejected row? | What you get |
|---|---|---|
| PostgreSQL | Yes | A DETAIL: Failing row contains (...) line with every value in the row. |
| DuckDB | Partly | Names the column and the offending value, as in Duplicate key "email: ada@example.com", but not the rest of the row. |
| SQL Server | Partly | Names the constraint and the table; the value only sometimes. |
| MySQL | Partly | Names the column or the duplicate value, as in Duplicate entry '1' for key. |
| SQLite | No | Names the constraint and the column only, as in UNIQUE constraint failed: signup.email. |
Learn more
Related
NOT NULL, DEFAULT, CHECK, UNIQUE, and keys.
A required column got no value.
The key already exists. Find the row that holds it.
A child points at a missing parent, or a parent has children.