Incident brief
Invalid input syntax
A string literal was cast to a type whose input function couldn't parse it. PostgreSQL rejected the value outright rather than guessing at a conversion.
What lands in your log
ERROR: invalid input syntax for type integer: "not_a_number"
In 10 seconds
- What triggers it
- Cast a string literal to a type whose input function can't parse it (e.g. a non-numeric string to integer).
- Fix
- Fix the literal so it matches the target type's actual input format.
- Proof
- Reproduced on PostgreSQL 16.14 → Casting a non-numeric string to integer was rejected with SQLSTATE 22P02, naming the exact invalid value. The session was unaffected afterward.
Fix
What to do right now
Application-level steps for this error.
- Fix the literal so it matches the target type's actual input format.
- For boolean specifically, only a documented set of strings, and their unique prefixes, are accepted; see the premium test.
- Don't rely on NULLIF to guard this generally, see the counterexample for why it only catches one specific value.
SELECT '42'::integer;For this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
Invalid input syntax (22P02) is statement-local: PostgreSQL does not retain the rejected value after the statement ends. Capture the exact bound value and statement position in application/server logs, then run this targeted validation before retrying.
Validate the exact input against the target type
Validate the specific value/shape that can raise this SQLSTATE.
-- Replace both placeholders with a safe literal and target type.
SELECT <input_literal>::text AS raw_input,
pg_typeof(NULL::<target_type>) AS target_type;Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual, not paraphrased.
PostgreSQL 16 Documentation, §8.6 Boolean Type
Unique prefixes of these strings are also accepted, for example t or n. Leading or trailing whitespace is ignored, and case does not matter.Read the full section on postgresql.org →
The invalid cast
integer's input function only accepts strings that parse as whole numbers. 'not_a_number' doesn't, so PostgreSQL rejected the value outright instead of guessing.Confirming the session still works
The rejected value never became a session-level problem, PostgreSQL refused the cast outright, so the next statement in session B 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.
- 1Cast a string literal to a type whose input function can't parse it (e.g. a non-numeric string to integer).
- 2PostgreSQL's type input function rejects the value.
- 3SQLSTATE 22P02 is reported, naming the exact string and target type.
One client: cast an invalid string literal to integer.
-- No table needed: the failure happens purely at the type-input-function stage.
SELECT 'no schema required' AS setup_note;SELECT 'not_a_number'::integer;SELECT 1 AS session_still_alive;What PostgreSQL actually returned
setup_note
--------------------
no schema required
(1 row)ERROR: invalid input syntax for type integer: "not_a_number"
LINE 1: SELECT 'not_a_number'::integer;
^ session_still_alive
----------------------
1
(1 row)The manual documents exactly which string representations boolean's input function accepts, including unique prefixes, whitespace, and case handling. This was tested directly, alongside a string that matches none of them.
Without this
Above: 'not_a_number'::integer has no valid parse and is rejected.
With this, tested
Below: boolean's documented prefixes and padded/mixed-case input are all accepted; a string matching none of them is still rejected.
- A second operational test: exact SQL, raw output, measured result, and engineer notes
- Fix that looks like a guard but only catches one value: 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.
Verification
- Last verified
- 2026-07-15 (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.