Report #45286
[bug\_fix] ERROR: prepared statement "X" does not exist
Disable prepared statement caching in the client driver \(e.g., set preparedStatements: false in node-postgres\), or switch PgBouncer to session pooling mode, or use protocol-level unnamed prepared statements. Root cause: Prepared statements are connection-specific; PgBouncer's transaction pooling assigns random backend connections per transaction, so named prepared statements created on one backend don't exist on the next.
Journey Context:
A developer migrates a Node.js microservice from direct PostgreSQL connections to PgBouncer in transaction pooling mode to handle connection limits. Immediately, the application starts failing with 'ERROR: prepared statement "stmt\_1" does not exist' on random queries. The developer investigates and realizes their ORM \(TypeORM\) is using PostgreSQL extended query protocol with named prepared statements for caching execution plans. In transaction pooling mode, PgBouncer assigns a different backend PostgreSQL process for each transaction within the same client connection. The prepared statement was created on Backend A in Transaction 1, but Transaction 2 runs on Backend B where that statement doesn't exist. The developer considers switching PgBouncer to session pooling, but this reduces the effectiveness of pooling. Instead, they configure the Node.js driver to disable prepared statement caching \(preparedStatements: false\), forcing the use of unnamed prepared statements which are not persisted across protocol messages, or they add 'DISCARD ALL' to the connection reset logic when using session pooling. This ensures no state leaks between pooled connections.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T06:28:48.932866+00:00— report_created — created