Skip to content
Postgres Default Password: Truth, Setup, and Reset

Click to use (opens in a new tab)

Postgres Default Password: Truth, Setup, and Reset

September 10, 2026 by Chat2DBChat2DB Team

Searching for the "postgres default password" is one of the most common things people do in their first hour with PostgreSQL, and the honest answer surprises most of them: there is no default password. A fresh PostgreSQL installation creates a superuser role named postgres with no password at all. Whether you can log in without one, must set one, or get a generated one depends entirely on how PostgreSQL was installed and on the authentication rules in pg_hba.conf. This article explains what each platform actually does, how to set or change the password, how to reset a forgotten one safely, what the common authentication errors mean, and how to keep the setup secure once it works.

Why PostgreSQL has no default password

PostgreSQL separates two things that other databases often blur together: who a role is, and how a connection proves it is that role. The postgres superuser is created by initdb when the data directory is initialized. Unless initdb was run with --pwprompt or --pwfile, the role's password column is simply NULL:

SELECT rolname, rolsuper, rolpassword IS NOT NULL AS has_password
FROM pg_authid
WHERE rolname = 'postgres';
 rolname  | rolsuper | has_password
----------+----------+--------------
 postgres | t        | f
(1 row)

How you get in is decided by pg_hba.conf (host-based authentication). Each line matches a connection type, database, user and source address to an authentication method. The methods that matter for this topic are:

  • peer: for local Unix-socket connections, the OS username must match the database role name. No password is involved.
  • trust: anyone who can reach the socket or port is allowed in as any role. No password is involved.
  • scram-sha-256 and md5: the client must present a password that matches the stored hash.

So "what is the postgres default password" is really "which method does my pg_hba.conf use for the connection I am making". Here is a typical file from a Debian package install:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             postgres                                peer
local   all             all                                     peer
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256

Read that carefully: over the Unix socket, postgres uses peer; over TCP to localhost, a password is required. That single file explains most of the confusion people run into.

How each platform behaves

Linux package installs (apt, dnf, zypper)

Distribution packages create an OS user named postgres and configure peer authentication for local socket connections. Since the OS user matches the database role, you log in by becoming that OS user:

sudo -u postgres psql
psql (16.4 (Ubuntu 16.4-1.pgdg22.04+1))
Type "help" for help.

postgres=#

If you instead run psql -U postgres as your own account, peer rejects you because your OS username is not postgres. And if you add -h localhost, you hit the TCP rule, which asks for a password that does not exist yet. Both errors are covered below.

Windows (EnterpriseDB installer)

The EDB installer for Windows prompts for a password during setup and applies it to the postgres superuser. There is no default here either; whatever you typed on that screen is the password. It also writes a pg_hba.conf that uses scram-sha-256 for all local connections, so psql -U postgres always asks for it. If you have forgotten what you typed, use the reset procedure below; reinstalling is not necessary.

macOS with Homebrew

Homebrew runs initdb as your own macOS user, so the superuser is not postgres but whatever whoami returns. The generated pg_hba.conf uses trust for local connections:

brew services start postgresql@16
psql postgres
psql (16.4 (Homebrew))
Type "help" for help.

postgres=# \du
                          List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 alice     | Superuser, Create role, Create DB, Replication, Bypass RLS

A postgres role may not exist at all. If a tool insists on it, create one: createuser -s postgres.

Postgres.app

Postgres.app behaves like Homebrew: the server runs as your macOS user, that user is the superuser, and local connections use trust. It does create a postgres role for convenience, again with no password. Connecting with psql -U postgres -h localhost works without a prompt because of the trust rule on localhost.

Docker postgres image

The official image refuses to start unless you tell it how to handle authentication. POSTGRES_PASSWORD is required; POSTGRES_USER optionally renames the superuser (default postgres); POSTGRES_DB sets the initial database (defaults to the user name).

docker run --name pg -e POSTGRES_PASSWORD=devpass -p 5432:5432 -d postgres:16

Omit the password and the container exits immediately with a clear message:

Error: Database is uninitialized and superuser password is not specified.
       You must specify POSTGRES_PASSWORD to a non-empty value for the
       superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".

       You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
       connections without a password. This is *not* recommended.

POSTGRES_HOST_AUTH_METHOD=trust writes host all all all trust into pg_hba.conf, which means anyone who can reach the published port is a superuser. It is acceptable for a throwaway local container and nothing else. Two more details trip people up: the environment variables are only honored on first initialization, so changing POSTGRES_PASSWORD on an existing volume does nothing; and inside the container, docker exec -it pg psql -U postgres works without a password because the image configures trust for local socket connections.

Docker Compose example

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD:?set DB_PASSWORD in .env}
      POSTGRES_DB: app
    ports:
      - "127.0.0.1:5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 5s
      retries: 10
 
volumes:
  pgdata:

Binding the port to 127.0.0.1 keeps the database off your LAN, and the ${DB_PASSWORD:?...} syntax makes Compose fail loudly instead of starting with an empty password.

Managed services

Cloud providers never expose a default password either. Amazon RDS asks for a master username and password when you create the instance, or generates one you can view once in the console or retrieve from Secrets Manager. Supabase and Neon generate a password at project creation and show it in the dashboard along with a ready-made connection string; if you lose it, both offer a reset button rather than a recovery option. In all of these, the "postgres default password" is whatever the provider issued you.

Setting or changing the postgres password

Once you can log in by any method, setting a password is one statement:

ALTER USER postgres WITH PASSWORD 'S3cure-and-long-passphrase';
ALTER ROLE

That statement puts the plaintext password in server logs if log_statement is all, and in your psql history. The \password meta-command avoids both by hashing client-side and sending only the hash:

postgres=# \password postgres
Enter new password for user "postgres": 
Enter it again: 

Verify that a hash is now stored and that it uses SCRAM:

SELECT rolname, left(rolpassword, 14) AS hash_prefix FROM pg_authid WHERE rolname = 'postgres';
 rolname  |  hash_prefix
----------+----------------
 postgres | SCRAM-SHA-256$

Setting a password does not by itself change how you authenticate. If pg_hba.conf still says peer for the socket, sudo -u postgres psql still works without prompting, and the password only matters for TCP connections. That is a reasonable configuration for a server.

Resetting a forgotten postgres password

If you cannot log in by any route, for example on Windows where every rule requires a password, you can temporarily relax pg_hba.conf. Do this only over a local connection, and revert immediately afterwards, because while the file says trust anyone on that machine is a superuser.

First locate the file. From any working session, SHOW hba_file; prints the path. Common locations:

/etc/postgresql/16/main/pg_hba.conf              # Debian, Ubuntu
/var/lib/pgsql/16/data/pg_hba.conf               # RHEL, Fedora
C:\Program Files\PostgreSQL\16\data\pg_hba.conf  # Windows EDB installer
/opt/homebrew/var/postgresql@16/pg_hba.conf      # Homebrew, Apple Silicon

Then follow these steps:

# 1. Back up the file
sudo cp /etc/postgresql/16/main/pg_hba.conf /etc/postgresql/16/main/pg_hba.conf.bak

# 2. Change the localhost line(s) from scram-sha-256 (or md5) to trust
#    host    all    all    127.0.0.1/32    trust
#    host    all    all    ::1/128         trust

# 3. Reload, no restart needed
sudo systemctl reload postgresql
# Windows: pg_ctl reload -D "C:\Program Files\PostgreSQL\16\data"
# or:      SELECT pg_reload_conf();  from any open session

# 4. Connect without a password and set a new one
psql -U postgres -h localhost -c "\password postgres"

# 5. Restore the backup and reload again
sudo cp /etc/postgresql/16/main/pg_hba.conf.bak /etc/postgresql/16/main/pg_hba.conf
sudo systemctl reload postgresql

# 6. Confirm the password is required again
psql -U postgres -h localhost -W

On Linux you often do not need any of this, because sudo -u postgres psql still works through peer regardless of the password. Try that first. In Docker, docker exec -it <container> psql -U postgres gives you the same shortcut.

Understanding the common errors

password authentication failed for user "postgres"

psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed:
FATAL:  password authentication failed for user "postgres"

The connection matched a scram-sha-256 or md5 rule and the password was wrong, empty, or not set at all. A role with a NULL password can never pass password authentication, so on a fresh Linux install this is what psql -U postgres -h localhost produces until you run ALTER USER. Also check that the client is not silently reading a stale entry from ~/.pgpass or the PGPASSWORD variable.

Peer authentication failed for user "postgres"

psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed:
FATAL:  Peer authentication failed for user "postgres"

You connected over the Unix socket as an OS user whose name is not postgres. The fix is one of three: run the client as that user (sudo -u postgres psql), add -h localhost to switch to the TCP rule and use the password, or change the socket rule to scram-sha-256 if you prefer passwords everywhere.

No pg_hba.conf entry for host

FATAL:  no pg_hba.conf entry for host "192.168.1.20", user "postgres", database "postgres", no encryption

No line matched the remote address at all. Add a host line with the client's CIDR and scram-sha-256, ensure listen_addresses in postgresql.conf includes the interface, and restart. Never resolve this by adding a trust line for 0.0.0.0/0.

scram-sha-256 versus md5

password_encryption controls how new passwords are hashed. Since PostgreSQL 14 the default is scram-sha-256; earlier versions defaulted to md5, which is a salted hash that is still vulnerable to replay if captured.

SHOW password_encryption;
 password_encryption
---------------------
 scram-sha-256

Two facts follow from this. First, a scram-sha-256 rule in pg_hba.conf cannot verify a password stored as MD5, so roles created on an old server must have their passwords re-set after the setting changes. Second, an md5 rule in pg_hba.conf will accept SCRAM-stored passwords, which makes it a safe intermediate step during migration. A quick audit of who still has MD5 hashes:

SELECT rolname FROM pg_authid WHERE rolpassword LIKE 'md5%';

Very old clients or drivers that do not implement SCRAM will fail with "authentication method 10 not supported"; upgrading the driver is the right fix rather than downgrading the server.

Connecting with the password

With psql, pass the user and force a TCP connection so the password rule applies; -W forces the prompt even if the server would not have asked:

psql -U postgres -h localhost -p 5432 -d postgres -W

The same connection expressed as a URI, which most drivers and tools accept:

postgresql://postgres:S3cure-and-long-passphrase@localhost:5432/postgres?sslmode=prefer

Keep in mind that a password in a URI ends up in shell history and process listings. For scripts, the ~/.pgpass file is the supported alternative. It must be readable only by you:

# ~/.pgpass  format: hostname:port:database:username:password
localhost:5432:*:postgres:S3cure-and-long-passphrase
chmod 600 ~/.pgpass
psql -U postgres -h localhost   # no prompt, password read from .pgpass

GUI clients ask for the same four pieces of information. In Chat2DB, for example, you create a PostgreSQL connection with host localhost, port 5432, user postgres and the password you set, and the same "password authentication failed" and "no pg_hba.conf entry" messages appear verbatim in the test-connection dialog if something is wrong, which makes them easy to diagnose with the sections above. You can download it from chat2db.ai/download (opens in a new tab).

Security hardening

The absence of a default password is a feature: PostgreSQL will not let a forgotten default become a backdoor. Keep it that way with a few rules.

  • Never use trust on a network address. It is fine for the Unix socket on a single-user laptop and nowhere else.
  • Never ship POSTGRES_HOST_AUTH_METHOD=trust to production, and do not publish port 5432 on 0.0.0.0 in Docker unless you have a firewall in front of it.
  • Set password_encryption = 'scram-sha-256' and use scram-sha-256 in every host line; retire md5.
  • Do not use the postgres superuser for applications. Create a role with only the privileges the application needs:
CREATE ROLE app_rw LOGIN PASSWORD 'another-long-passphrase';
GRANT CONNECT ON DATABASE app TO app_rw;
GRANT USAGE ON SCHEMA public TO app_rw;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_rw;
  • Prefer .pgpass, environment injection from a secrets manager, or client certificates over passwords embedded in URIs and config files committed to Git.
  • Require TLS for remote connections with hostssl lines, and consider VALID UNTIL on role passwords that must rotate.
  • After any emergency edit of pg_hba.conf, diff it against the backup before you walk away.

Summary

There is no postgres default password. Linux packages log you in with peer as the postgres OS user, Homebrew and Postgres.app make your own account the superuser with trust, the Windows installer makes you choose a password, the Docker image refuses to start without POSTGRES_PASSWORD, and managed services generate one for you. Set a password with \password postgres or ALTER USER, reset a forgotten one by briefly switching localhost to trust and reverting, use scram-sha-256, and keep the superuser away from application code. Once those pieces are in place, the "password authentication failed" and "peer authentication failed" errors stop being mysteries and become simple statements about which pg_hba.conf line your connection matched.