Postgres Error: 'database "..." does not exist' — Cause, Fix, and Troubleshooting Guide
Fix Postgres FATAL: database "appdb" does not exist — wrong dbname, dropped DB, wrong port or cluster, CREATE DATABASE, fix your DSN.
- #postgres
- #postgresql
- #database
- #troubleshooting
Stuck on this Postgres error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
PostgreSQL rejects the connection at authentication time when the database named in your connection request is not present in the cluster you reached. The server never gets to running a query — it fails while selecting the target database.
FATAL: database "appdb" does not exist
The name in quotes is exactly what the client asked for. If that string is not a row in pg_database on the cluster you connected to, you get this FATAL. The catch is that “the cluster you connected to” may not be the one you think, so the fix is often about where you connected, not just what you named.
Symptoms
- The connection dies immediately with the
FATALabove; no query ever runs. psql -d appdbfails, butpsql -d postgreson the same host/port succeeds.- The app worked in one environment and fails in another with the same code.
- A freshly provisioned server rejects the app’s database until it is created.
$ psql "postgresql://app_user@10.0.3.44:5432/appdb"
psql: error: connection to server at "10.0.3.44", port 5432 failed:
FATAL: database "appdb" does not exist
Common Root Causes
1. Wrong dbname in the connection string
A typo, a stale environment variable, or a copied DSN pointing at the wrong database name. The most common case is simply that the name never matched.
-- Connect to a database that always exists, then check what is really there:
SELECT datname FROM pg_database ORDER BY datname;
datname
-----------
postgres
template0
template1
(3 rows)
appdb is absent — the DSN is asking for a database that was never created here.
2. Database never created, or dropped
New environments start with only postgres, template0, and template1. If your bootstrap/migration step did not run, the app database does not exist. A DROP DATABASE (manual cleanup, a reset script, a rolled-back restore) has the same effect.
3. Connected to the wrong cluster or port
Two Postgres instances on one host (5432 and 5433), a local instance shadowing a remote one, or a Docker container versus the host package. appdb exists on one and not the other.
SELECT inet_server_addr() AS server_ip, inet_server_port() AS port;
4. Case sensitivity of quoted names
CREATE DATABASE "AppDB" creates a database whose name is literally AppDB. Connecting to appdb (lowercased) will not find it, because the quoted name preserved the mixed case.
SELECT datname FROM pg_database WHERE datname = 'AppDB';
5. Template / maintenance database confusion
Assuming a database like app exists because postgres does, or trying to connect to template0 (which disallows connections). The maintenance database postgres is not your application database.
How to diagnose
Step 1: Confirm which cluster you actually reached
Connect to a database you know exists (postgres) and print the server coordinates:
SELECT current_database() AS db,
inet_server_addr() AS host,
inet_server_port() AS port,
version();
If the host/port here is not what you expected, you are on the wrong cluster and the missing database lives elsewhere.
Step 2: List every database on that cluster
SELECT datname, datallowconn
FROM pg_database
ORDER BY datname;
Or from the shell:
$ psql -h 10.0.3.44 -p 5432 -U app_user -d postgres -l
Name | Owner | Encoding | ...
-----------+----------+----------+----
postgres | postgres | UTF8 |
orders | app_user | UTF8 |
template0 | postgres | UTF8 |
template1 | postgres | UTF8 |
If the target name is missing here, it does not exist on this cluster — create it or fix where you are pointing.
Step 3: Check for a case-sensitivity mismatch
Compare what you asked for against what exists, case-exact:
SELECT datname
FROM pg_database
WHERE lower(datname) = lower('appdb');
A row of AppDB returned for a request of appdb means the database exists but under a quoted, mixed-case name.
Fixes
Create the database if it should exist
Connect to postgres (or any existing database) and create the target:
CREATE DATABASE appdb OWNER app_user;
From the shell:
$ createdb -h 10.0.3.44 -U app_user appdb
Fix the connection string
Point the DSN at the correct name, host, and port. Verify each field:
postgresql://app_user@10.0.3.44:5432/appdb
└ host └ port └ dbname (must match pg_database)
Update the environment variable or secret that feeds the DSN, then restart the app so it picks up the change.
Connect to the maintenance database first
When you only need to administer, connect to postgres and work from there. Never target template0 — it has datallowconn = false and refuses connections by design.
$ psql -h 10.0.3.44 -p 5432 -U app_user -d postgres
Match the exact (quoted) case
If the database was created with a quoted mixed-case name, connect with that exact spelling, or recreate it lowercased for sanity:
-- Reference the exact name:
SELECT datname FROM pg_database WHERE datname = 'AppDB';
-- Or standardize on a lowercase name:
CREATE DATABASE appdb OWNER app_user;
What to watch out for
- The quoted name in the error is authoritative — copy it exactly when comparing against
pg_database. - Two clusters on one host is the classic trap: always confirm host and port, not just dbname.
template0never accepts connections; usepostgresas your entry point instead.- Unquoted identifiers fold to lowercase, but
CREATE DATABASE "AppDB"preserves case — avoid quoted mixed-case names to prevent this class of bug. - After
CREATE DATABASE, remember roles and grants do not carry over; the new database still needs its schema and privileges.
Related
- Postgres Error: ‘role ”…” does not exist’
- Postgres Error: ‘could not connect to server: Connection refused’
- Postgres Error: ‘relation does not exist’
Fixed it? Get 500 Postgres & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.