Incident brief
Bind message parameter mismatch
A Bind message in the extended query protocol supplied a different number of parameter values than the prepared statement expected. PostgreSQL rejected it as a protocol violation.
What lands in your log
ERROR: bind message supplies 2 parameters, but prepared statement "" requires 1
In 10 seconds
- What triggers it
- Prepare a query with one placeholder ($1) using psql's extended-protocol \bind meta-command.
- Fix
- Match the number of bound parameter values to the number of placeholders the statement actually declares.
- Proof
- Reproduced on PostgreSQL 16.14 → A Bind message supplying 2 parameter values for a statement with 1 placeholder was rejected with SQLSTATE 08P01. The identical statement with 1 value succeeded.
Fix
What to do right now
Application-level steps for this error.
- Match the number of bound parameter values to the number of placeholders the statement actually declares.
- In a real client driver, this usually means fixing the parameter array passed to the prepared/parameterized query call.
SELECT $1::int \bind 5
\gFor this error
See this error live on the server
Run these against the affected instance to confirm the diagnosis before you act.
08P01 is a frontend/backend protocol violation; malformed Bind messages are diagnosed from server/driver logs, not table state. Confirm the client build and prepared-statement parameter contract.
Prepared statement parameter contracts still visible
For surviving sessions, compare declared parameter_types with what the driver claims it bound.
SELECT name, parameter_types, from_sql, statement
FROM pg_prepared_statements
ORDER BY prepare_time;Connection identity for affected clients
Group current clients by application and address to isolate one driver build or proxy path.
SELECT application_name, client_addr, backend_type, count(*) AS sessions
FROM pg_stat_activity
GROUP BY application_name, client_addr, backend_type
ORDER BY sessions DESC;Why it happens
What PostgreSQL is telling you
The mechanism behind the error, grounded in the official manual, not paraphrased.
PostgreSQL 16 Documentation, psql, \bind
\bind [ parameter ] ... Sets query parameters for the next query execution ... This command causes the extended query protocol ... to be used, unlike normal psql operation, which uses the simple query protocol.Read the full section on postgresql.org →
Bind with 2 values for 1 placeholder
The query has exactly one placeholder ($1), but the Bind message supplied two values, the server rejects this at the protocol level, before the query ever runs, as SQLSTATE 08P01.Bind with 1 value for 1 placeholder
With the parameter count corrected to match the one placeholder, the Bind message is valid and the query executes normally.Reproduce & verify
A real, single-session PostgreSQL reproduction using the extended query protocol
A literal transcript of SQL run against a live PostgreSQL instance in an isolated lab. The commands below are exactly what was executed.
- 1Prepare a query with one placeholder ($1) using psql's extended-protocol \bind meta-command.
- 2Supply two bound values instead of one.
- 3SQLSTATE 08P01 is reported: the Bind message doesn't match what the parsed statement requires.
One client: psql's \bind meta-command sends a real Bind message using the extended query protocol, not the ordinary simple query protocol psql normally uses.
-- No schema needed: this reproduces at the wire-protocol level.
SELECT 'no schema required' AS setup_note;SELECT $1::int \bind 1 2
\gSELECT $1::int \bind 5
\gWhat PostgreSQL actually returned
setup_note
--------------------
no schema required
(1 row)ERROR: bind message supplies 2 parameters, but prepared statement "" requires 1 int4
------
5
(1 row)The deeper lab audit for this error
- Where the protocol-level boundary actually sits: 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.
Runbook to fix this
The runbook for this incident
Full step-by-step fixes for the condition behind this error: the diagnosis, the exact SQL, and output captured in the lab.
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-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.