How to fix Duplicate prepared statement in PostgreSQL

PostgreSQLINTERMEDIATEMEDIUMUpdated Dec 27, 2025· 144 views

This PostgreSQL error occurs when you attempt to create a prepared statement with a name that already exists in the current session. The solution is to deallocate the previous statement or use a different name.

Quick fix

Fixes 42P05

DEALLOCATE PREPARE statement_name;
PREPARE statement_name AS SELECT * FROM table WHERE id = $1;
  1. Check if you can simply use DEALLOCATE before PREPARE
  2. Use unnamed prepared statements to avoid name collisions
  3. If using JDBC drivers, set prepareThreshold=0
  4. For PgBouncer users, switch to session pooling or disable prepared statements
postgresql — error
DEALLOCATE PREPARE statement_name;
PREPARE statement_name AS SELECT * FROM table WHERE id = $1;
Duplicate prepared statement

What this error means

In PostgreSQL, prepared statements are named server-side objects that persist for the duration of a database session. Each prepared statement name must be unique within a single session. When PostgreSQL encounters an attempt to create a prepared statement with a name that already exists—without first deallocating the previous statement—it raises error code 42P05 (duplicate_prepared_statement). This typically happens in application code where prepared statements are created dynamically or in loops without proper cleanup. The error can also occur when reusing connection pooled connections that retain prepared statements from previous transactions.

Typical symptoms

  • Application throws error: 'ERROR: prepared statement "[name]" already exists (SQLSTATE 42P05)'
  • Error occurs when the same prepared statement name is prepared multiple times in a session
  • In connection pooling setups, intermittent failures when different requests reuse the same connection
  • Transaction fails and rolls back, but the prepared statement still exists in the session

Common causes

  1. Preparing a statement with the same name without calling DEALLOCATE first
  2. Application logic loops multiple times creating prepared statements without cleanup
  3. Connection pooling scenario where prepared statements from one transaction persist to the next
  4. Error handling that doesn't clean up prepared statements when transaction rollback occurs
  5. Driver-level prepared statement caching with non-unique statement names

How to fix "Duplicate prepared statement"

1Check if you can simply use DEALLOCATE before PREPARE

If you control the prepared statement creation, add a DEALLOCATE statement before re-preparing with the same name. This removes the existing statement and allows you to create a new one with that name.

sql
DEALLOCATE PREPARE statement_name;
PREPARE statement_name AS SELECT * FROM table WHERE id = $1;

Alternatively, use the DEALLOCATE ALL command to clear all prepared statements:

sql
DEALLOCATE ALL;
2Use unnamed prepared statements to avoid name collisions

PostgreSQL allows unnamed prepared statements (empty string as name). When you use an unnamed statement, any previous unnamed statement is automatically replaced without error.

sql
-- This replaces any previous unnamed statement automatically
PREPARE AS SELECT * FROM users WHERE id = $1;
EXECUTE (1);
DEALLOCATE;

This approach avoids the naming issue entirely for simple use cases.

3If using JDBC drivers, set prepareThreshold=0

Java applications using PostgreSQL JDBC drivers sometimes see this error due to the driver's automatic prepared statement caching. Disable automatic prepared statement caching by adding the prepareThreshold parameter to your connection string:

bash
jdbc:postgresql://localhost:5432/mydb?prepareThreshold=0

This parameter tells the driver not to automatically convert queries to prepared statements, eliminating the naming collision issue. Note this may have performance implications for query-heavy applications.

4For PgBouncer users, switch to session pooling or disable prepared statements

When using PgBouncer (a PostgreSQL connection pooler), prepared statements created in one client connection may collide if requests route to different database connections.

Option 1: Switch PgBouncer to 'session' pooling mode instead of 'transaction' mode in pgbouncer.ini:

ini
pool_mode = session

Option 2: Disable prepared statement caching in your application when using PgBouncer.

Session pooling ensures the same client always uses the same backend connection, preserving prepared statement state.

5Use unique names with timestamps or session identifiers

If you must create multiple prepared statements with similar purposes, generate unique names for each:

sql
-- Using timestamp
PREPARE stmt_<timestamp> AS SELECT * FROM users WHERE id = $1;

-- Using application ID or session identifier
PREPARE stmt_<app_id>_<query_hash> AS SELECT * FROM users WHERE id = $1;

This approach prevents name collisions while still allowing you to manage lifecycle of multiple statements.

Advanced notes

Name Truncation Issue: PostgreSQL truncates prepared statement names to 63 characters (NAMEDATALEN). If two different prepared statements have the same first 63 characters, they will collide. Ensure your naming scheme produces names shorter than 63 characters.

Statement Persistence Across Transactions: Unlike some databases, PostgreSQL prepared statements persist across transaction rollbacks within the same session. If a transaction fails after creating a prepared statement, you must still deallocate it before reusing the name.

Connection Pooling Considerations: Different pooling modes (transaction vs session) have different implications for prepared statements. Transaction pooling can route requests to different backend connections, so prepared statements from one transaction may not be available in the next. Understanding your pooling strategy is crucial for applications that rely on prepared statements.

Frequently asked questions

What does "42P05" mean?
In PostgreSQL, prepared statements are named server-side objects that persist for the duration of a database session. Each prepared statement name must be unique within a single session. When PostgreSQL encounters an attempt to create a prepared statement with a name that already exists—without first deallocating the previous statement—it raises error code 42P05 (duplicate_prepared_statement).
How do I fix "42P05"?
This PostgreSQL error occurs when you attempt to create a prepared statement with a name that already exists in the current session. The solution is to deallocate the previous statement or use a different name.
What causes "42P05"?
Preparing a statement with the same name without calling DEALLOCATE first Application logic loops multiple times creating prepared statements without cleanup Connection pooling scenario where prepared statements from one transaction persist to the next
Is the "42P05" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading