# 42P05 — Duplicate prepared statement

> PostgreSQL SQLSTATE 42P05: Duplicate prepared statement (duplicate_prepared_statement), source-backed diagnosis and recovery guidance.
---

# 42P05 — Duplicate prepared statement

## At a glance {#at-a-glance}

`42P05` (**duplicate_prepared_statement**) means the current backend/session already has a named prepared statement with that name. Pool reuse can expose this state from an earlier request, while a different connection can have a separate statement of the same name.

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| Field | Value |
| --- | --- |
| SQLSTATE | `42P05` |
| Condition | `duplicate_prepared_statement` |
| Status | `active` |
| Known present by | `7.4` |
| Locked snapshots | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| Macros | `ERRCODE_DUPLICATE_PSTATEMENT` |
| Aliases | `—` |

<!-- source facts: data/errcodes/42P05.json -->
<!-- END SQLSTATE FACTS -->

## Meaning {#meaning}

`StorePreparedStatement` keeps named statements in the backend's `prepared_queries` hash. `HASH_ENTER` reports ERROR `prepared statement "%s" already exists` when the name is already present, before the new plan is saved. `DEALLOCATE name` removes one entry and `DEALLOCATE ALL` removes the current backend's entries; these operations do not remove a statement owned by another connection.

## Diagnosis {#diagnosis}

Check the physical connection/backend identity, `pg_prepared_statements`, pool checkout history, and the PREPARE path. Distinguish a named server statement from the unnamed protocol statement and from a driver-local cache key. If two requests used the same pool connection, inspect the exact name and parameter types before changing the SQL.

## Response {#response}

Reuse the existing statement only when its SQL and parameter types match. Otherwise coordinate `DEALLOCATE name` with the owner of that connection, use a unique deterministic name, or reset the pool session under an explicit lifecycle policy. Do not issue `DEALLOCATE` on an unrelated connection and assume it cleared the collision. Recover an explicit transaction after this `ERROR` with a savepoint rollback or transaction rollback; reconnecting is a controlled reset, not a universal fix.

## Messages {#messages}

The confirmed 18.6 variant is explicit `ERROR`: `prepared statement "%s" already exists`. `%s` is the dynamic server-side name.

## Versions {#versions}

From 7.4 through 18.6 and 19beta3; that catalogue range is not a precise introduction claim. The selected 18.6 source covers insertion and current-backend deallocation, and runtime was not run.

## Related {#related}

- [`26000`](../26000/)
- [`42P04`](../42p04/)
- [`42P07`](../42p07/)

## Sources {#sources}
- `src.errcodes.42P05.18.6` — `src/backend/utils/errcodes.txt` line 381, fixed at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L381)).

- `src.call.42P05.b490336894ec11628c1766f2` — `src/backend/commands/prepare.c` lines 412-415, fixed at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; SHA-256 `e37fbd5f7618e5554561d9293d8c3af7cf3190c62c5c6bbceb3fe8b97be17956` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/prepare.c#L412-L415)).
- `src.call.42P05.lifecycle` — `src/backend/commands/prepare.c` lines 401-423 and 504-511, fixed at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; SHA-256 `e37fbd5f7618e5554561d9293d8c3af7cf3190c62c5c6bbceb3fe8b97be17956` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/prepare.c#L401-L423)).
- `src.calls.REL_18_6.42P05` — resolved core call groups; SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf`.
- [`authored evidence`](../data/evidence/42p05.json) — source claims, message roles, and runtime boundary.
