Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for Postgres By James Joyner IV · · 8 min read Last reviewed Jul 2026

Postgres Error: 'database "..." does not exist' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix Postgres FATAL: database "appdb" does not exist — wrong dbname, dropped DB, wrong port or cluster, CREATE DATABASE, fix your DSN.

Part of the PostgreSQL Database Errors hub
  • #postgres
  • #postgresql
  • #database
  • #troubleshooting
Free toolkit

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 FATAL above; no query ever runs.
  • psql -d appdb fails, but psql -d postgres on 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.
  • template0 never accepts connections; use postgres as 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.
Free download · 368-page PDF

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?

Free download · 368-page PDF

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.