Report #81628
[bug\_fix] ERROR: prepared statement "S\_1" does not exist \(or protocol error with prepared statements\)
Disable prepared statements \(server-side prepares\) in the client driver when using PgBouncer in transaction pooling mode. For JDBC, set prepareThreshold=0; for psycopg2, set prepare\_threshold=None; for other drivers, use the equivalent option to prevent the driver from issuing Parse/Bind protocol messages.
Journey Context:
An application is moved from a direct PostgreSQL connection to using PgBouncer in transaction pooling mode to handle higher concurrency. Immediately, the application starts throwing errors about missing prepared statements or protocol mismatches. The errors seem random and correlate with high load. Investigation reveals that the application uses an ORM \(like Hibernate or SQLAlchemy\) that automatically uses server-side prepared statements for repeated queries. In PgBouncer's transaction mode, each query might use a different backend connection from the pool. When the driver sends a Bind message referencing prepared statement "S\_1" on a new connection that doesn't have it defined \(because it was prepared on a different connection\), the backend returns an error. The fix involves checking the PgBouncer documentation on prepared statements and reconfiguring the client driver to disable server-side prepares, forcing the driver to use simple query protocol or to unprepare/reprepare on each transaction boundary.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T19:36:18.878391+00:00— report_created — created