- SQLSTATE
- 3D000
- Condition name
invalid_catalog_name- Product
- PostgreSQL
- Versions
- PostgreSQL 13 to 18 (SQL-level examples run on PostgreSQL 18.6 in PGlite)
- Last reviewed
- 24 October 2026
On this page
What it means
SQLSTATE 3D000 means the database named in the connection or in a statement does not exist on this server.
A PostgreSQL connection is always to one database, named in the connection string. If no database with that name exists on the server, the login ends with FATAL: database "..." does not exist and SQLSTATE 3D000 (invalid_catalog_name). The documentation points out a common trap: if you do not specify a database name, it defaults to the database user name, so psql -U andym with no database tries to connect to a database called andym. Connection parameters are taken literally, so the name must match exactly, including upper and lower case.
Inside a session, statements that name a database (ALTER DATABASE, DROP DATABASE, GRANT ... ON DATABASE, CREATE DATABASE ... TEMPLATE, functions such as pg_database_size) raise the same SQLSTATE as a normal ERROR. In SQL, unquoted names are folded to lower case: a database created as "SalesApp" must be written with the quotes, or PostgreSQL looks for salesapp. PostgreSQL has no cross-database queries, so a three-part name such as otherdb.public.t is not a way to reach another database.
Common causes
- A typo or wrong environment in the database name (dbname in the connection string, the PGDATABASE environment variable, or the application configuration).
- No database given, so the client used the role name as the database name and no such database exists.
- The database has not been created yet on this server: a new environment, a restore that has not run, or a container whose initialisation script did not create it.
- The client is connected to a different server or port than intended, which has other databases.
- A mixed-case database name written without double quotes in SQL, so PostgreSQL looks for the lower-case name.
- A script runs DROP or ALTER DATABASE on a database that was already removed or renamed.
Diagnose it
Read-only These queries only read the system catalogs (pg_catalog, information_schema) and statistics views such as pg_stat_activity and pg_locks. They do not change data, roles or settings, so they are safe to run first.
Which databases exist on this server?
Connect to a database that exists (postgres is created by default) and list them; psql's \l shows the same.
SELECT datname, datallowconn
FROM pg_database
ORDER BY datname; The exact names, with their case. If the name you used is not there, you are either on the wrong server or the database has not been created.
Look for the name ignoring case
SELECT datname
FROM pg_database
WHERE lower(datname) = lower('SalesApp'); A row such as SalesApp means the database exists with mixed case: write it as "SalesApp" in SQL.
Confirm which server and database you are on
SELECT current_database(),
current_user,
current_setting('port') AS port,
current_setting('data_directory') AS data_directory; Useful when several PostgreSQL servers run on one machine or in containers: the port and data directory show which one answered. Reading data_directory needs superuser or pg_read_all_settings.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Connect to the right database name
Client or network sidePass the database explicitly: psql -d testdb, dbname=testdb in a connection string, or the database part of a URI (postgresql://andym@server.joe.com:5432/testdb). Check that PGDATABASE or the application setting is not overriding it.
Create the database
Changes schemaIf the database should exist, create it with the right owner (or use the createdb program). Restores with pg_restore -C create it for you.
CREATE DATABASE testdb OWNER andym;
Quote mixed-case names in SQL
Changes configurationUse double quotes for a database created with upper-case letters. Better still, use lower-case names for new databases so quoting is never needed.
ALTER DATABASE "SalesApp" SET work_mem = '64MB';
Use IF EXISTS in scripts
Changes schemaFor clean-up scripts that may run twice, DROP DATABASE IF EXISTS issues a notice instead of an error when the database is already gone.
Caution: DROP DATABASE permanently removes the database and all its data. Check the name and the server first, and take a backup if there is any doubt.
DROP DATABASE IF EXISTS old_reporting;
Examples
Connecting to a database that does not exist
Shown as documented in the PostgreSQL documentation (Client Authentication, Authentication Problems). The same happens with no dbname at all when no database is named after the role, because the database name then defaults to the user name. This example needs a running PostgreSQL server (a login to a named database), which PGlite does not provide, so it was not reproduced here.
-- From a shell:
-- psql "host=server.joe.com dbname=testdb user=andym"
FATAL: database "testdb" does not exist
A mixed-case database name without quotes
CREATE DATABASE "SalesApp";
ALTER DATABASE SalesApp SET work_mem = '64MB';
ERROR: database "salesapp" does not exist
Reproduced on PGlite 0.5.11 (PostgreSQL 18.6 compiled to WebAssembly), 24 October 2026.
Dropping a database that is not there
DROP DATABASE nosuchdb;
ERROR: database "nosuchdb" does not exist
Reproduced on PGlite 0.5.11 (PostgreSQL 18.6 compiled to WebAssembly), 24 October 2026.
Creating a database from a missing template
CREATE DATABASE copydb TEMPLATE nosuchtemplate;
ERROR: template database "nosuchtemplate" does not exist
Reproduced on PGlite 0.5.11 (PostgreSQL 18.6 compiled to WebAssembly), 24 October 2026.
How to prevent it
Name the database explicitly in every connection string and keep one source of connection settings per environment. Create databases in the provisioning step (an init script, infrastructure code or a migration tool) so applications never start before their database exists.
Use lower-case database names without special characters, and use IF EXISTS / IF NOT EXISTS patterns in scripts that may run more than once.
Common questions
How do I fix "database does not exist" in PostgreSQL?
List the databases (SELECT datname FROM pg_database, or \l in psql) while connected to postgres, then either connect with the exact existing name or create the database with CREATE DATABASE. Make sure you are connected to the right server and port.
Why does psql try to connect to a database with my user name?
When no database is given, PostgreSQL uses the user name as the database name. Pass -d postgres (or the database you want) to connect somewhere else.
The database is listed, so why do I still get this error?
In SQL, unquoted names are folded to lower case, so a database created as "SalesApp" must be written with double quotes. Also check for leading or trailing spaces and that you are on the same server where you listed it.
Learn more on CodeWithSQL
Official documentation
Last technically reviewed 24 October 2026; examples and diagnostics run on PostgreSQL 18.6 documentation; SQL-level parts in PGlite 0.5.11. SQL-level examples were run in PGlite (PostgreSQL compiled to WebAssembly); examples that need a running server are shown as documented in the PostgreSQL documentation.