Skip to content
PostgreSQL

PostgreSQL Error 3D000

database does not exist

Applies to: PostgreSQL 13 to 18 (SQL-level examples run on PostgreSQL 18.6 in PGlite)
Last technically reviewed 24 October 2026 on PostgreSQL 18.6 documentation; SQL-level parts in PGlite 0.5.11
The full message
FATAL:  database "testdb" does not exist
Other forms of this message
In a SQL statement such as ALTER DATABASE, DROP DATABASE or GRANT ... ON DATABASE
ERROR:  database "nosuchdb" does not exist
CREATE DATABASE with a missing template
ERROR:  template database "nosuchtemplate" does not exist
As psql prints the login failure (host and address illustrative)
psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: FATAL:  database "testdb" does not exist
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

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;
What to look for

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');
What to look for

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;
What to look for

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 side

Pass 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 schema

If 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 configuration

Use 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 schema

For 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"
Result
FATAL:  database "testdb" does not exist

A mixed-case database name without quotes

CREATE DATABASE "SalesApp";

ALTER DATABASE SalesApp SET work_mem = '64MB';
Result
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;
Result
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;
Result
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.

Still stuck on a PostgreSQL error?

Browse the full PostgreSQL error library, or get hands-on help from an experienced SQL professional.