PostgreSQL error 23502 (Not Null Violation) explained: what it means, why it happens, and how to fix it — with copy-paste code examples.
Read the error for the exact column that received NULL. If that does not apply, provide an explicit non-null value in the INSERT or fix the application mapping — the full checklist is below.
SQLSTATE: 23502
Official name: Not Null Violation
System name: not_null_violation
Service: PostgreSQL
A NOT NULL constraint was violated by inserting or updating a column with a NULL value.
You may see this error reported as one of the following messages:
null value in column "email" of relation "users" violates not-null constraintA signup form posts without the email field; the backend builds INSERT INTO users (email, name) VALUES (NULL, 'John') even though email is NOT NULL. PostgreSQL rejects it with SQLSTATE 23502: null value in column "email" of relation "users" violates not-null constraint. The other common variant is adding NOT NULL to an existing column that already contains NULLs — the ALTER TABLE itself fails.
Run these to confirm the cause before applying a fix — each command answers a specific question.
SELECT attname, attnotnull
FROM pg_attribute
WHERE attrelid = 'users'::regclass AND attnum > 0 AND NOT attisdropped;
attnotnull = t marks the mandatory columns; cross-check against the columns your INSERT actually sets.
SELECT count(*) FROM users WHERE email IS NULL;
Non-zero means an ALTER TABLE ... SET NOT NULL will fail — backfill first.
Error on INSERT/UPDATE?
├─ the value is genuinely absent → make it required upstream (form/API validation)
└─ a default exists → use INSERT ... VALUES (DEFAULT, ...)
Error when ALTER TABLE ADD COLUMN NOT NULL?
└─ backfill NULLs first (UPDATE ... SET col = default WHERE col IS NULL),
then apply the constraint — or add it as NOT VALID and VALIDATE later
UPDATE users SET email = 'unknown@example.com' WHERE email IS NULL;
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
Never add NOT NULL to a column containing NULLs; backfill first or the constraint fails for existing rows.
Mark fields as required (non-optional) in schema.prisma; the client will type-check before sending NULL.
model User {
id Int @id @default(autoincrement())
email String // required, cannot be null
}
Use null=False with a default, or validate in clean() before save().
class MyModel(models.Model):
email = models.EmailField(null=False, default='')
Declare nullable=False on the column; the ORM rejects None before reaching the DB.
class User(Base):
__tablename__ = 'users'
email = Column(String, nullable=False)
Most often this happens when omitting a required column in an INSERT statement, or when passing NULL/undefined from the application for a NOT NULL column.
Read the error for the exact column that received NULL.
This page documents fixes for: prisma, django, sqlalchemy.
Recommendations are editorial — DB Error Reference takes no payment or affiliate fees for tool listings.
This page is based on the official PostgreSQL documentation linked below and adds practical troubleshooting guidance on top.