42830
Read PG 18 manual ↗invalid_foreign_key
- SQLSTATE
- 42830
- Condition name
- invalid_foreign_key
- Class
- Syntax Error or Access Rule Violation
- Source macro
- ERRCODE_INVALID_FOREIGN_KEY
- 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
42830 is invalid_foreign_key: an FK definition cannot find a qualifying unique key on referenced columns. The case references a parent integer column with no unique constraint.
Meaning
Creation checks the parent key before any child row is inserted. The fixed primary is there is no unique constraint matching given keys for referenced table "%s". For an ordinary FK, the referenced column set may match an eligible unique index in a different physical order; the source matcher rejects duplicate referenced columns and requires the right count, uniqueness, validity, and no partial predicate or index expressions. A matching deferrable unique/primary index takes a separate source-only 55000 path. This is definition-time, unlike 23503, and the selected autocommit ALTER leaves IDLE.
Diagnosis
Compare the referenced column set with pg_constraint and pg_index. Check for duplicate references, the number of key columns, unique/primary status, validity, partial predicates, and expressions; physical index order need not equal the FK list order for the ordinary path. Also check indimmediate: a matching deferrable key is rejected with 55000, rather than the selected 42830. Matching data types alone do not make a referenced key eligible.
Response
Add or use an intentional non-deferrable unique key over the referenced column set, then create the FK. Check the business meaning of the parent table's key and desired NULL/MATCH semantics; adding an overly broad unique constraint can change accepted data. Do not reorder a valid index merely to mirror the FK syntax, and do not mistake a partial or expression index for a qualifying key. The case adds UNIQUE (id) then creates one FK. In an explicit transaction, the rejected ALTER TABLE leaves INERROR; roll back or return to a suitable savepoint before retrying. The selected autocommit path returns to IDLE.
Observed diagnostics
The selected tablecmds.c group is explicit ERROR with primary there is no unique constraint matching given keys for referenced table "%s" and no detail or hint. The same matcher has a source-only 55000 (object_not_in_prerequisite_state) variant, cannot use a deferrable unique constraint for referenced table "%s", when the otherwise matching key is deferrable.
Representative case
The registry creates parent and child tables, attempts the FK, adds the parent unique key, creates the valid FK, and counts it.
CREATE TABLE syntax_schema.fk_parent (id integer);
CREATE TABLE syntax_schema.fk_child (parent_id integer);
ALTER TABLE syntax_schema.fk_child ADD CONSTRAINT fk_bad FOREIGN KEY (parent_id) REFERENCES syntax_schema.fk_parent (id);
ALTER TABLE syntax_schema.fk_parent ADD CONSTRAINT fk_parent_id_key UNIQUE (id);
ALTER TABLE syntax_schema.fk_child ADD CONSTRAINT fk_good FOREIGN KEY (parent_id) REFERENCES syntax_schema.fk_parent (id);
SELECT count(*) FROM pg_constraint c JOIN pg_namespace n ON n.oid = c.connamespace WHERE n.nspname = 'syntax_schema_name' AND c.conname = 'fk_good' AND c.contype = 'f';
The selected 18.6 and 10.21 runs passed SQLSTATE, severity, state/recovery, repair, cleanup, and isolated-target stop assertions. See case JSON and authored evidence; private manifest and registry hashes are recorded there.
Versions
The locked catalogue contains this condition from the 7.4 presence bound through the listed snapshots. The selected natural case passed on PostgreSQL 18.6 and 10.21; that bounded result does not infer every intermediate release or every source branch.
Sources
src.errcodes.REL_18_6— fixed definition at724edf9bde9d356724ad384a2e196edc3c9f80f7; SHA-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba(source).src.invalid-fk.18.6—src/backend/commands/tablecmds.clines 13639–13642 at724edf9bde9d356724ad384a2e196edc3c9f80f7; blob SHA-256422dc8e833df4940755973c757e338295822ba3e4c7266c40669f49f96eb15a9(source).src.invalid-fk.10.23—src/backend/commands/tablecmds.clines 8133–8136 at02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4; blob SHA-2566de441c88496c6cf57a836898388085ec08bf69afd70d07acdafd6089b9b5f8c(source).src.invalid-fk-guards.18.6— completetransformFkeyCheckAttrsinsrc/backend/commands/tablecmds.clines 13505–13642 at724edf9bde9d356724ad384a2e196edc3c9f80f7; blob SHA-256422dc8e833df4940755973c757e338295822ba3e4c7266c40669f49f96eb15a9(source).src.invalid-fk-guards.10.23— completetransformFkeyCheckAttrsinsrc/backend/commands/tablecmds.clines 8002–8136 at02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4; blob SHA-2566de441c88496c6cf57a836898388085ec08bf69afd70d07acdafd6089b9b5f8c(source).src.calls.REL_18_6/src.calls.REL_10_23— fixed call scans, SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf/00d16d3eb01b71ccf1b245c8f3102f9d0ec9f36fb02777b8dd1b99fcb263040c.manifest.42830/snippet-registry.42830— hashes are recorded inevidence/42830.jsonand each runtime record.
Source evidence
Evidence belongs to the frozen source and runtime versions listed here. It is not a runtime verification of the selected manual version.
42830 is the invalid_foreign_key condition in Class 42.
Method: Read fixed errcodes.txt and locked catalogue metadata.
Limits: Identity does not identify every backend call that can reuse this SQLSTATE.
The selected fk_missing_unique_key follows a resolved PostgreSQL source-call group; the complete matcher accepts a duplicate-free referenced column set in any physical order only when the candidate index has the required count, uniqueness, validity, and no predicate or expressions.
Method: Trace the REL_18_6 and REL_10_23 source-call records at the locked commits.
Limits: This is one mechanism boundary, not an exhaustive inventory of the code.
src.invalid-fk.18.6 src.invalid-fk.10.23 src.invalid-fk-guards.18.6 src.invalid-fk-guards.10.23
The same matcher rejects a duplicate referenced-column list with 42830 and rejects an otherwise matching deferrable unique or primary index with OBJECT_NOT_IN_PREREQUISITE_STATE (55000); the latter is source-only in this review.
Method: Read the complete transformFkeyCheckAttrs function in both locked tablecmds.c snapshots.
Limits: The selected runtime covers only the missing-key 42830 case and does not observe the duplicate-list or deferrable branches.
The selected fk_missing_unique_key passed on isolated PostgreSQL 18.6 and 10.21 targets.
Method: Run the shared SQL registry and inspect SQLSTATE, severity, state, repair, cleanup, and target stop.
Limits: Scope is limited to these statements, psycopg, and two versions.
The locked catalogue records 42830 from the 7.4 presence bound through the listed snapshots; runtime scope is 18.6 and 10.21.
Method: Read generated facts, fixed calls, and selected summaries.
Limits: Definition presence is not an exact behavioral introduction; two runtime versions do not prove every intermediate behavior.
src.errcodes.REL_18_6 src.calls.REL_18_6 src.calls.REL_10_23
- src/backend/utils/errcodes.txt · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 raw/calls/REL_18_6.jsonl· ·raw/calls/REL_10_23.jsonl· ·- src/backend/commands/tablecmds.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - src/backend/commands/tablecmds.c · REL_10_23 ·
02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4 - src/backend/commands/tablecmds.c · REL_18_6 ·
724edf9bde9d356724ad384a2e196edc3c9f80f7 - src/backend/commands/tablecmds.c · REL_10_23 ·
02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4 verify/cases/42830/cases.json· ·verify/cases/42830/snippets.json· ·
Message templates
explicit ERROR · message.fk_missing_unique_key
Primary
there is no unique constraint matching given keys for referenced table "%s"
explicit ERROR · message.deferrable-unique
Primary
cannot use a deferrable unique constraint for referenced table "%s"
Reproduction & repair cases
fk_missing_unique_key · PG 10, 18
Preconditions
- A runner-owned disposable target is provisioned.
Trigger: Create a foreign key referencing a parent column with no unique constraint.
Expected assertions
- SQLSTATE is 42830 with the missing referenced unique-key message
- The failed autocommit session remains IDLE
- Adding a parent UNIQUE constraint then the FK creates one valid constraint
Repair: Add a deliberate primary/unique key over the referenced columns before defining the FK; matching types alone are insufficient.
Cleanup: Drop the runner schema and both tables.
Recorded runtime evidence
18.6 (Homebrew) · passed
Run: syntax2-42830-latest
{
"diagnostic": {
"text": "there is no unique constraint matching given keys for referenced table \"fk_parent\"",
"context": null,
"severity": "ERROR",
"sqlstate": "42830",
"table_name": null,
"column_name": null,
"schema_name": null,
"source_file": "tablecmds.c",
"source_line": "13642",
"message_hint": null,
"datatype_name": null,
"exception_type": "InvalidForeignKey",
"internal_query": null,
"message_detail": null,
"constraint_name": null,
"message_primary": "there is no unique constraint matching given keys for referenced table \"fk_parent\"",
"source_function": "transformFkeyCheckAttrs",
"internal_position": null,
"statement_position": null,
"severity_nonlocalized": "ERROR"
},
"failed_status": "IDLE",
"repair_status": "IDLE",
"foreign_key_count": 1,
"connection_autocommit": true
}10.21 (Debian 10.21-1.pgdg90+1) · passed
Run: syntax2-42830-pg10
{
"diagnostic": {
"text": "there is no unique constraint matching given keys for referenced table \"fk_parent\"",
"context": null,
"severity": "ERROR",
"sqlstate": "42830",
"table_name": null,
"column_name": null,
"schema_name": null,
"source_file": "tablecmds.c",
"source_line": "8136",
"message_hint": null,
"datatype_name": null,
"exception_type": "InvalidForeignKey",
"internal_query": null,
"message_detail": null,
"constraint_name": null,
"message_primary": "there is no unique constraint matching given keys for referenced table \"fk_parent\"",
"source_function": "transformFkeyCheckAttrs",
"internal_position": null,
"statement_position": null,
"severity_nonlocalized": "ERROR"
},
"failed_status": "IDLE",
"repair_status": "IDLE",
"foreign_key_count": 1,
"connection_autocommit": true
}Definition snapshot: english-manuals:643c7c4b93d620680acf10f8508… · English manual source