# 42P04 — Duplicate database

> PostgreSQL SQLSTATE 42P04: Duplicate database (duplicate_database), source-backed diagnosis and recovery guidance.
---

# 42P04 — Duplicate database

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

`42P04` (**duplicate_database**) means a database-management path found the requested name already in the cluster. It is a cluster-level name check, not a relation collision in the current database, and the CREATE and RENAME callers have different surrounding guards.

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

| Field | Value |
| --- | --- |
| SQLSTATE | `42P04` |
| Condition | `duplicate_database` |
| 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_DATABASE` |
| Aliases | `—` |

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

## Meaning {#meaning}

In `createdb`, `get_database_oid(dbname, true)` checks the proposed database name and raises ERROR `database "%s" already exists`. `RenameDatabase` performs the same check against `newname`, after looking up the old database, checking ownership, and checking the `CREATEDB` privilege. The `%s` therefore names the requested database in CREATE or the new name in RENAME.

The utility dispatcher calls `PreventInTransactionBlock(isTopLevel, "CREATE DATABASE")` before it enters `createdb`. A CREATE DATABASE attempted inside an explicit transaction is therefore a separate transaction-block failure, not evidence that `42P04` was emitted. The RENAME path has its own old-name, owner, privilege, and new-name checks.

## Diagnosis {#diagnosis}

Verify the target cluster and exact name in `pg_database`, including identifier folding and the possibility that another migration won a race. For CREATE, inspect the proposed name and template/owner prerequisites separately. For RENAME, inspect both old and new names plus ownership and `CREATEDB`; do not diagnose a missing old database or a privilege failure as `42P04`.

## Response {#response}

If the existing database is intended, make orchestration idempotent and inspect it rather than repeating CREATE DATABASE. Otherwise choose an unused name. Run CREATE DATABASE at top level, outside an explicit transaction block. For RENAME, choose an unused new name only after verifying the old database, ownership, `CREATEDB`, active sessions, dependencies, and cluster identity. If a RENAME ERROR occurs inside an explicit transaction, issue `ROLLBACK` before the next command, or `ROLLBACK TO` a savepoint created before the rename when the outer transaction must be retained. Drop or rename is not a generic repair for every `42P04`.

## Messages {#messages}

The selected groups are explicit `ERROR` with `database "%s" already exists`: `createdb` supplies the requested name and `RenameDatabase` supplies the new name. The dispatcher’s `PreventInTransactionBlock` guard is source evidence for CREATE DATABASE’s separate transaction restriction, not another `42P04` message.

## Versions {#versions}

From 7.4 through 18.6 and 19beta3; that catalogue range is not a precise introduction claim. The selected CREATE, RENAME, and dispatcher guards are fixed 18.6 source paths; no runtime case was run.

## Related {#related}

- [`42P07`](../42p07/)
- [`42P06`](../42p06/)
- [`42710`](../42710/)

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

- `src.call.42P04.465a77b5605c341bc91f6990` — `src/backend/commands/dbcommands.c` lines 1393-1395, fixed at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; SHA-256 `64b77d2197dce16eb1ad19d8168382459d621a03df0b00be157f7db39ca22acf` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/dbcommands.c#L1393-L1395)).
- `src.call.42P04.b0d1644def83c14a7504fec4` — `src/backend/commands/dbcommands.c` lines 1949-1951, fixed at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; SHA-256 `64b77d2197dce16eb1ad19d8168382459d621a03df0b00be157f7db39ca22acf` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/dbcommands.c#L1949-L1951)).
- `src.call.42P04.create-tx-guard` — `src/backend/tcop/utility.c` lines 769-773, fixed at `724edf9bde9d356724ad384a2e196edc3c9f80f7`; SHA-256 `7aae5d07628b6debf8456d1d4ea96f28912232192e56ea25773b4c4b61235a00` ([source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/utility.c#L769-L773)).
- `src.calls.REL_18_6.42P04` — resolved core call groups; SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf`.
- [`authored evidence`](../data/evidence/42p04.json) — source claims, message roles, and runtime boundary.
