Postgres 3D000: database does not exist
Fix PostgreSQL 3D000 database does not exist by confirming the database name, connection target, and default-database fallback in tools.
Symptoms
- FATAL: database "appdb" does not exist
- psql connects to the default database because -d was omitted
- The error appears after copying a connection string between environments
Possible causes
- The database name in the connection string is wrong or absent
- The database was never created on this server
- A tool defaulted to the username or postgres database
- The connection targets a different port or host with a differently named database
Diagnosis steps
List databases on the target server
psql -h host -U app -lInterpretation
Confirming the exact database name and spelled spelling eliminates guesswork.
Connect specifying the database explicitly
psql -h host -U app -d appdbInterpretation
If this works, the application connection string is missing or misnaming the database.
Compare environment connection strings
Interpretation
A string copied from staging can still point at a database that does not exist in production.
Root cause
3D000 means the server is reachable and authentication succeeded, but no database with the requested name exists. Because psql and many clients default the database to the username or postgres, an omitted -d or a missing database name in a URL silently targets the wrong database.
Fix
Create the database with CREATE DATABASE if missing, and always specify it explicitly in the connection string. Verify the exact name (case matters for quoted identifiers) against the server listing, and ensure migrations run against the intended database so it is provisioned.
Verify the fix
Connect with the explicit database name from psql and the application; both succeed, and psql -l lists the database, confirming it exists on the target server.
Symptoms
The server returns FATAL: database "appdb" does not exist. Authentication is fine, so the failure is at database selection rather than credentials.
Diagnosis
List databases and connect explicitly:
psql -h db.internal -U app -l
psql -h db.internal -U app -d appdb
Without -d, psql defaults to the username database, which may not exist.
Fix
Create and always name the database:
CREATE DATABASE appdb OWNER app;
postgresql://app:[email protected]:5432/appdb
Verification
Connect from psql and the application with the explicit name; both succeed, and psql -l lists appdb, confirming the target database exists.
Tool Defaults That Hide the Target
The subtle part of 3D000 is that a missing name is often supplied silently rather than being empty. psql falls back to a database named after the connecting user; some ORMs fall back to the username or to postgres; a load-balancing proxy may preserve the client database but route to a node where only one database exists. Logging the fully resolved connection target, including database, host, and port, exposes these defaults immediately. In container environments, also confirm the connection is not pointing at a sidecar or an old volume whose database was dropped.