23502
Read PG 18 manual ↗not_null_violation
- SQLSTATE
- 23502
- Condition name
- not_null_violation
- Class
- Integrity Constraint Violation
- Source macro
- ERRCODE_NOT_NULL_VIOLATION
- Evidence
- Observed at runtime in the source evidence
English SQLSTATE atlas: authored explanations and source/runtime evidence are separate from the manual definitions. View source ↗
At a glance
23502 means a NULL reached a NOT NULL rule. The selected case identifies column label and relation items; the exact PG18 and PG10 primary messages differ slightly in relation wording, while the SQLSTATE and structured object identity agree.
Meaning
The executor checks the tuple against the relation’s NOT NULL attributes and reports 23502 with the column and relation. PostgreSQL also uses the code for schema validation and domain NOT NULL validation, with different source templates; a failing domain CHECK is a 23514 path instead. A default, an explicit value, a generated expression, or a schema change may be the correct repair depending on why the NULL was produced.
Diagnosis
Capture the exact column_name, table_name, and optional failing-row detail. The selected PG18 primary includes of relation "items", while PG10 omits that phrase; use structured fields rather than matching the full English string. Trace the value through application parameters, casts, generated columns, triggers, and INSERT ... SELECT; do not infer the source from the final row alone. The selected autocommit case remained IDLE after the failed insert, but an explicit transaction must be rolled back or handled before reuse.
Response
Supply a value that is valid for the column, intentionally apply a default, or change the constraint only after checking existing rows and downstream readers. Do not drop NOT NULL or replace it with a weaker CHECK merely to silence a missing-value error; make NULLability a deliberate data-contract decision. Retry the insert with the corrected value. For a migration that adds NOT NULL, validate existing data separately and keep the schema change’s transaction boundary explicit.
Observed diagnostics
18.6 (Homebrew) / latest:SQLSTATE 23502; primary null value in column "label" of relation "items" violates not-null constraint; DETAIL Failing row contains (2, null).; status_after_error IDLE.
10.21 (Debian 10.21-1.pgdg90+1) / pg10:SQLSTATE 23502; primary null value in column "label" violates not-null constraint; DETAIL Failing row contains (2, null).; status_after_error IDLE.
Representative case
The runner reads these statements from verify/cases/23502/snippets.json (SHA-256 f701e32a0e9214d6c88deabcda99981c288cae0f176d1dcaf383863c3942f8e0) and qualifies the temporary table names; the complete setup, assertions, and cleanup are in the case export.
-- create
CREATE TABLE items(id integer PRIMARY KEY, label text NOT NULL);
-- seed
INSERT INTO items VALUES (1, 'seed');
-- trigger
INSERT INTO items VALUES (2, NULL);
-- repair
INSERT INTO items VALUES (2, 'valid');
-- verify
SELECT id, label FROM items ORDER BY id;
The SQLSTATE, diagnostic, transaction-state, and repair assertions for this excerpt are produced from the shared registry; structured evidence · case export.
Authored evidence IDs: identity, dml-path, schema-path, runtime. Selected runtime records: runtime.23502-batch1-latest-20260909.latest, runtime.23502-batch1-pg10-20260909.pg10.
Versions
The locked catalogue observes the condition by 7.4 and in all listed formal snapshots. The selected runtime is one ordinary INSERT on 18.6 and 10.21; it does not cover ALTER TABLE validation, domains, partition routing, or trigger-generated NULLs.
Sources
src.errcodes.18.6(SHA-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)src.calls.REL_18_6(SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)src.execMain.18.6(SHA-25633b97337fa23a649c5e7a092e1bd405a54e8503529236c62c9d5bb93a1774a8d)src.tablecmds.18.6(SHA-256422dc8e833df4940755973c757e338295822ba3e4c7266c40669f49f96eb15a9)src.typecmds.18.6(SHA-25660d1e9754646e100f6b74aa367ad8c2c52386c400df721707423d329209c47eb)doc.ddl-constraints.18.6(SHA-256ce1919d9236f2e71672660e1a347146472e966e4d19b77fde5ae345dd1db6ec7) · official documentation
Source evidence
Evidence belongs to the frozen source and runtime versions listed here. It is not a runtime verification of the selected manual version.
23502 is not_null_violation in Class 23.
Method: Read the fixed errcodes row.
Limits: The code says that a NOT NULL rule failed; it does not by itself distinguish DML from schema validation.
The executor reports 23502 when a tuple has a NULL value for a NOT NULL column, with column/relation fields and an optional failing-row DETAIL.
Method: Trace ReportNotNullViolationError and its errtablecol metadata.
Limits: The DETAIL can be omitted or vary with row-description settings; use structured column/table diagnostics.
ALTER TABLE validation and domain NOT NULL validation use separate 23502 source templates; domain CHECK validation is a 23514 path.
Method: Compare the tablecmds and executor report groups.
Limits: A repair must satisfy the actual schema rule; adding a default or relaxing NOT NULL is a migration decision, not a generic retry.
The selected insert case returned 23502 on PG18.6 and PG10.21, identified label/items, stayed IDLE in autocommit mode, and then inserted a valid row.
Method: Read the selected summaries and raw diagnostics.
Limits: The case covers one INSERT path and not ALTER TABLE, domains, partitions, or trigger-generated NULLs.
runtime.23502-batch1-latest-20260909.latest runtime.23502-batch1-pg10-20260909.pg10
- src/backend/utils/errcodes.txt · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 raw/calls/REL_18_6.jsonl· ·- src/backend/executor/execMain.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - src/backend/commands/tablecmds.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - doc/src/sgml/ddl.sgml · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - src/backend/commands/typecmds.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7
Message templates
ERROR · insert
Primary
null value in column "%s" of relation "%s" violates not-null constraint
Detail
Failing row contains %s.
The %s substitutions are the column, relation, and optional row description.
ERROR · schema-not-null-validation
Primary
column "%s" of relation "%s" contains null values
This validation template reports existing rows while a relation schema is being validated.
ERROR · domain-not-null-validation
Primary
column "%s" of table "%s" contains null values
This template is used while validating a domain NOT NULL rule against columns that use the domain.
Reproduction & repair cases
not_null_insert · PG 10, 18
Preconditions
- The target column is declared NOT NULL
- The insert supplies a NULL value
Trigger: Insert a row with NULL in the NOT NULL column.
Expected assertions
- SQLSTATE is 23502
- The column and relation are identified
- A valid row can be inserted after the error
Repair: Provide a valid value or change the schema only after confirming the data contract; do not silently coerce a missing value without business meaning.
Cleanup: Drop the case schema with an owner connection.
Recorded runtime evidence
18.6 (Homebrew) · passed
Run: 23502-batch1-latest-20260909
{
"rows": [
[
1,
"seed"
],
[
2,
"valid"
]
],
"table": "items",
"column": "label",
"detail": "Failing row contains (2, null).",
"primary": "null value in column \"label\" of relation \"items\" violates not-null constraint",
"sqlstate": "23502",
"status_after_error": "IDLE"
}10.21 (Debian 10.21-1.pgdg90+1) · passed
Run: 23502-batch1-pg10-20260909
{
"rows": [
[
1,
"seed"
],
[
2,
"valid"
]
],
"table": "items",
"column": "label",
"detail": "Failing row contains (2, null).",
"primary": "null value in column \"label\" violates not-null constraint",
"sqlstate": "23502",
"status_after_error": "IDLE"
}Definition snapshot: english-manuals:a74cbd8fa3a212c2c61d9a9e545… · English manual source