Incident brief
Too many rows
A PL/pgSQL SELECT ... INTO STRICT matched more than one row. PostgreSQL raised an error instead of silently picking one of them.
What lands in your log
ERROR: query returned more than one row
In 10 seconds
- What triggers it
- Run SELECT ... INTO STRICT against a query that matches two or more rows.
- Fix
- Add ORDER BY plus LIMIT 1 to the STRICT select if exactly one specific row is genuinely the right answer.
- Proof
- Reproduced on PostgreSQL 16.14 → A SELECT ... INTO STRICT that matched two rows was rejected with SQLSTATE P0003. The session was unaffected afterward.
Fix
What to do right now
Application-level steps for this error.
- Add ORDER BY plus LIMIT 1 to the STRICT select if exactly one specific row is genuinely the right answer.
- Or restructure the query to aggregate or otherwise guarantee a single row, if that's the actual intent.
DO $$
DECLARE
x int;
BEGIN
SELECT n INTO STRICT x FROM (VALUES (1),(2)) t(n) ORDER BY n LIMIT 1;
RAISE NOTICE 'x = %', x;
END $$;For this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
Too many rows is raised by SELECT ... INTO STRICT. Count the rows for the exact predicate without STRICT before deciding whether the data or the query contract is wrong.
Cardinality of the STRICT predicate
Replace the read-only query from the function; the predicate is invalid for STRICT when this test is true.
SELECT count(*) AS rows_returned,
count(*) > 1 AS would_raise_p0003
FROM (<strict_select_without_into>) AS candidate;Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual, not paraphrased.
PostgreSQL 16 Documentation, Executing a Command with a Single-Row Result (43.5.3)
If the STRICT option is specified, the command must return exactly one row or a run-time error will be reported, either NO_DATA_FOUND (no rows) or TOO_MANY_ROWS (more than one row).Read the full section on postgresql.org →
The STRICT select with two matching rows
Per the manual, STRICT requires exactly one row back, two rows raises TOO_MANY_ROWS (SQLSTATE P0003) instead of silently picking one and discarding the other.Confirming the session still works
The STRICT SELECT INTO block is what raised TOO_MANY_ROWS, nothing leaks out to the session, so its next statement runs normally.Reproduce & verify
A real, single-session PostgreSQL reproduction
A literal transcript of SQL run against a live PostgreSQL instance in an isolated lab. The commands below are exactly what was executed.
- 1Run SELECT ... INTO STRICT against a query that matches two or more rows.
- 2SQLSTATE P0003 is reported; the block aborts.
One client: a DO block runs SELECT ... INTO STRICT against an inline VALUES list matching two rows.
-- No table needed: the failure is self-contained via an inline VALUES list.
SELECT 'no schema required' AS setup_note;DO $$
DECLARE
x int;
BEGIN
SELECT n INTO STRICT x FROM (VALUES (1),(2)) t(n);
END $$;SELECT 1 AS session_still_alive;What PostgreSQL actually returned
setup_note
--------------------
no schema required
(1 row)ERROR: query returned more than one row
HINT: Make sure the query returns a single row, or use LIMIT 1.
CONTEXT: PL/pgSQL function inline_code_block line 5 at SQL statement session_still_alive
---------------------
1
(1 row)The deeper lab audit for this error
- Fix that hides the error but leaves a silent, arbitrary pick: exact SQL, output, and verdict
- A manual-grounded production interpretation of the lab result
Card required. Cancel before day 7 and you are not charged.
Connected
Everything this error touches
Every page this SQLSTATE connects to: the concept that explains it, the runbooks that fix it, the parameters you tune to prevent it, and the sibling errors it travels with. All real cross-references. Jump straight in, or open the full interactive map.
Related errors
Verification
- Last verified
- 2026-07-16 (Docker lab, PostgreSQL 16.14)
- Verification scope
- Verified against PostgreSQL 16.14 in an isolated lab environment
- Audit status
- reviewed
Went further?
Pro unlocks the second lab proof
Free page stops the bleeding. Pro adds the operational test, SQLSTATE audit, and deeper evidence, same error, more certainty.