Diagnostic Queries
Symptoms
An INSERT supplied an explicit value for a column defined as GENERATED ALWAYS (a generated/identity column). Such columns compute their own value, so PostgreSQL raises SQLSTATE 428C9 (generated_always).
- The column is
GENERATED ALWAYS(identity or stored). - A HINT suggests using
OVERRIDING SYSTEM VALUEor DEFAULT. - Common with identity primary keys.
What the server log shows
ERROR: cannot insert a non-DEFAULT value into column "id"
DETAIL: Column "id" is an identity column defined as GENERATED ALWAYS.
HINT: Use OVERRIDING SYSTEM VALUE to override.
Why PostgreSQL raises this — what the manual says
the CREATE TABLE reference (GENERATED … AS IDENTITY):
“The clauses ALWAYS and BY DEFAULT determine how explicitly user-specified values are handled in INSERT and UPDATE commands.”
A GENERATED ALWAYS column is owned by the system (identity sequence or a computed expression). Supplying an explicit value conflicts with that ownership, so PostgreSQL rejects it with 428C9 unless explicitly overridden.
Common causes
- Inserting an explicit value into an identity/generated column.
- An ORM including the identity column in the insert list.
- Copying rows including a GENERATED ALWAYS column.
How to fix it
- Omit the column so it is generated, or set it to
DEFAULT. - Use
INSERT … OVERRIDING SYSTEM VALUEwhen you must supply a value (e.g. data migration). - Configure the ORM to treat the column as database-generated.
Related & next steps
Reference: PostgreSQL 18 — CREATE TABLE.
Thanks — noted. This helps keep the database accurate.