PostgreSQL error: null value violates not-null constraint
ERROR: null value in column "email" of relation "users" violates not-null constraint
DETAIL: Failing row contains (42, null, Alice, 2026-07-09 10:12:00).
The write would have left a NOT NULL column empty, so PostgreSQL rejected it. The DETAIL line shows the entire failing row, with values in the table's column order — line it up against \d output and you can see exactly what arrived.
What this error means
One mechanism here surprises almost everyone at some point: column defaults apply only when the column is omitted from the INSERT (or explicitly given the DEFAULT keyword). An INSERT that lists the column and passes NULL means NULL — the default does not kick in. ORMs that serialize every mapped field, sending null for unset ones, silently disable your database defaults this way.
Common causes
- INSERT omitting a required column that has no default.
- Explicit NULL from the application (the ORM pattern above) overriding an existing DEFAULT.
- UPDATE setting the column to NULL, directly or via a computation that produced NULL.
- Data loads: in
COPY ... CSV, an unquoted empty field is read as NULL (a quoted empty string""is not).
How to diagnose it
\d users -- quali colonne sono NOT NULL, quali hanno un DEFAULT
Map the DETAIL row onto the column list to identify the offending field, then find who produced the NULL: application payload, ORM serialization, or the input file. Logging the actual SQL the app sends settles the "but we set a default!" conversations quickly.
How to fix it
- Provide the value, or add a genuine default:
ALTER TABLE users ALTER COLUMN created_at SET DEFAULT now(); - ORM sending NULLs → configure it to omit unset columns, or set the default in the model as well as the database.
- CSV loads → control NULL handling explicitly (
NULL ''option, or clean the file); load into a staging table when in doubt. - If NULL is actually legitimate for the business, drop the constraint deliberately:
ALTER TABLE users ALTER COLUMN email DROP NOT NULL;— a decision, not a workaround.
