You spin up PostgreSQL (locally, in Docker, or on a fresh VPS), type the password you set during install — and PostgreSQL says:
$ psql -U postgres -h localhost
Password for user postgres:
psql: error: connection to server on host "localhost" (127.0.0.1), port 5432 failed: FATAL: password authentication failed for user "postgres"
The Stack Overflow thread with ~1.6M views (Q19070362) lists three causes, in order of frequency:
- The role has no password set — common after a fresh install that only used peer auth.
-
pg_hba.conf method mismatch —
md5vsscram-sha-256disagreeing on which algorithm to validate the stored hash against. - You typed the wrong password — common after restoring a dump, switching databases, or copy-pasting from a password manager that mangled a special character.
Here are the fixes for each.
Fix 1 — Set a password on the role
The most common case: the role exists but has no password. Peer auth let you in as the postgres OS user, but TCP connections require a password.
sudo -u postgres psql
ALTER USER postgres PASSWORD 'a-strong-dev-password';
That works for the default postgres superuser. For your own role (say mahdi), connect as the role owner first:
sudo -u postgres psql -c "ALTER USER mahdi PASSWORD 'a-strong-dev-password';"
ALTER USER ... PASSWORD rewrites the stored verifier using whichever algorithm password_encryption is set to in postgresql.conf (default scram-sha-256 on PG 14+). The password is hashed on the server — it never leaves the cluster in plaintext after the auth handshake.
Fix 2 — Switch pg_hba.conf from md5 to scram-sha-256
If you set a password and still get the error, the method declared in pg_hba.conf does not match the algorithm used to hash the stored verifier. Check the line that applies to your connection.
sudo -u postgres psql -c 'SHOW hba_file;'
Open the file. The relevant line depends on whether you connect over TCP (host) or local socket (local):
# IPv4 local connections:
host all all 127.0.0.1/32 scram-sha-256
# IPv6 local connections:
host all all ::1/128 scram-sha-256
# Local socket:
local all all scram-sha-256
If you see md5 instead of scram-sha-256, change it. SCRAM-SHA-256 (RFC 5802) is the secure default on PostgreSQL 10+ and is what password_encryption = scram-sha-256 (the default) writes. md5 is legacy and vulnerable to replay of stolen password hashes.
Reload — pg_hba.conf is re-read on reload, not on every connection:
sudo systemctl reload postgresql
# or, if you start pg manually:
pg_ctl reload -D /var/lib/postgresql/data
Setting the method to trust makes the error go away by disabling authentication entirely — any local user can connect as any role, including the superuser. Fine on an isolated throwaway VM, dangerous on any shared or developer machine. Use scram-sha-256 and a real password.
Fix 3 — Verify the password you typed
Less common but easy to miss:
-
Trailing whitespace.
psqlreads the password via/dev/tty; some terminals strip or add whitespace depending on how the password is pasted. Type it manually to be sure. -
Special characters in shell. If you pass the password via
PGPASSWORD=foo\!bar psql ...,\!is interpreted by bash. Use single quotes (PGPASSWORD='foo!bar') or a.pgpassfile with mode 0600. -
Wrong user.
psql -U postgreswith a connection string-h localhostconnecting asmahdi— the role name in the error message is the one PostgreSQL tried to authenticate. Re-read the error message.
Use a .pgpass file (avoids shell quoting and password prompts)
# ~/.pgpass (chmod 0600, owned by your user)
localhost:5432:*:postgres:your-strong-password
Format: hostname:port:database:username:password. With mode 0600 and matching ownership, psql uses it automatically without prompting. Useful in scripts and CI.
Supabase local dev
The Supabase CLI (supabase start) runs a Postgres container with peer auth disabled — every connection is over TCP with md5 or scram-sha-256. Common gotchas:
- The
postgresrole password is set byPOSTGRES_PASSWORDinsupabase/.env(defaultpostgres). Connect topostgresql://postgres:postgres@localhost:54322/postgres. - If you changed
POSTGRES_PASSWORDand the data directory was already initialized, the password baked into the catalog is still the old one. Recreate the volume:supabase stop && supabase start(deletes local data — back up first). - For Studio, the connection string is
postgresql://postgres:postgres@db:5432/postgresfrom inside the docker network, orpostgresql://postgres:postgres@localhost:54322/postgresfrom the host.
Docker (vanilla postgres image)
The official postgres image bakes POSTGRES_PASSWORD into the initialized data directory. You cannot ALTER USER it inside the container and have it persist across restarts — the data volume is the source of truth.
# Reset: drop the volume so it re-initializes with POSTGRES_PASSWORD
docker compose down
docker volume rm <project>_postgres-data
docker compose up -d postgres
For a quick override without resetting:
docker exec -it <container> psql -U postgres -c "ALTER USER postgres PASSWORD 'new-pw';"
# ...but this is lost on the next `docker compose down` if the volume persists.
For real work, set POSTGRES_PASSWORD and POSTGRES_USER in compose env and let the volume initialize once.
Common mistakes
-
Typed
postgresas the user but the role is named differently — the error message names the role PostgreSQL tried, not the one you think you used. Check-Uand the connection string. -
Edited the wrong
pg_hba.conf— there can be several (Debian vs Homebrew vs Docker). Confirm withSHOW hba_file;before editing. -
Forgetting to reload —
pg_hba.confis re-read onpg_ctl reload, not on every connection. Runsystemctl reload postgresqlorpg_ctl reload -D .... -
password_encryptionismd5but you switched pg_hba.conf toscram-sha-256— the new hash is md5, but pg_hba.conf validates as scram-sha-256. CheckSHOW password_encryption;and align it withpg_hba.conf(both should bescram-sha-256). -
Bypassing with
trust— disables auth. Usescram-sha-256and a real password. -
Supabase local password mismatch —
POSTGRES_PASSWORDonly takes effect on data-dir init. Changing it aftersupabase startrequiressupabase stop && rm -rf supabase/.branches && supabase start. -
.pgpasswrong permissions — psql ignores~/.pgpassif mode is not 0600 (or 0640 with the right owner).chmod 600 ~/.pgpass.
Official references: PostgreSQL — Client Authentication (pg_hba.conf), PostgreSQL — Password Authentication, PostgreSQL — The Password File (.pgpass).
Related Articles
- Fix: Peer Authentication Failed for User "postgres"
- How to Show Tables in PostgreSQL (psql + Supabase)
- PostgreSQL DESCRIBE TABLE: The psql backslash-d Equivalent
- How to Switch Database in psql
- PostgreSQL Slow Queries Fix
- Supabase Slow Queries Fix
Originally published at https://www.iloveblogs.blog
Top comments (0)