PostgreSQL "Peer authentication failed for user": connect the right way, or change pg_hba.conf
Fix PostgreSQL "Peer authentication failed for user": use sudo -u postgres, connect over TCP with -h localhost, or change pg_hba.conf to scram-sha-256 and reload.
by OhSudo ··
Checked on real software: PostgreSQL · November 2026How we check
Not sure this is your cause?Find it step by step: Can't connect to the database →
Part of a learning path:SQL and PostgreSQL, step by step
$ psql -U postgrespsql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: Peer authentication failed for user "postgres"You have a fresh PostgreSQL, you asked for a user, and it refuses without even asking for a password.
With peer authentication, PostgreSQL asks the operating system who’s connecting over the local socket, and that name has to match the database user. You’re logged in as alex, and asked for postgres, so they don’t match. It’s the default for local connections on Debian and Ubuntu. No password is involved, and that’s why none of the passwords you try make any difference.
- Linux user alexruns psql -U postgresconnects over
- Local socketthe OS says: alexmust match(fails)
- Database user postgresalex ≠ postgres(breaks here)
TL;DR
To get in as the admin:
sudo -u postgres psqlFor an application with its own user and password, connect over TCP, so the password rules apply:
psql -h localhost -U app -d shop1. Connect as the matching system user
The usual way to administer PostgreSQL, and it’s fine as it is:
sudo -u postgres psqlsudo -u postgres createuser --pwprompt appsudo -u postgres createdb -O app shopThere’s no need to give the postgres user a password for this.
2. Connect over TCP instead
The rule depends on how you connect. Local socket and TCP are separate lines in the configuration, and adding -h switches:
psql -U app -d shop # socket: peerpsql -h localhost -U app -d shop # TCP: passwordCheck the current rules, from inside psql as an admin:
type | database | user_name | address | auth_method-------+----------+-----------+-------------+--------------- local | {all} | {postgres}| | peer local | {all} | {all} | | peer host | {all} | {all} | 127.0.0.1 | scram-sha-256A connection string with a host, such as postgresql://app:secret@localhost/shop, already uses TCP, so applications often don’t run into this at all. Applications that connect with no host set use the socket, and fail with this error. Set the host.
The user needs a password for that. If it has none:
The Password Generator gives you a strong one. Use its shell-safe option if it goes in a connection URL. If this now fails with a different message, see “password authentication failed”.
3. Change the rule for local connections
If you want passwords on the socket too, edit pg_hba.conf. Find it first:
sudo -u postgres psql -c 'SHOW hba_file;'It’s usually /etc/postgresql/18/main/pg_hba.conf on Ubuntu, and /var/lib/pgsql/18/data/pg_hba.conf on RHEL. Change the second local line, and leave the postgres one alone:
# TYPE DATABASE USER METHODlocal all postgres peerlocal all all scram-sha-256The order matters. PostgreSQL uses the first line that matches, and never looks further. A rule below a broader one is never reached.
Then reload, which needs no restart:
sudo systemctl reload postgresqlAnd test:
psql -U app -d shopKeeping peer for postgres means that sudo -u postgres psql still works. If you change that one too and don’t know its password, you’ve locked yourself out, so keep a session open while you test.
4. Map a system user to a database user
Maybe the system user and the database user are legitimately different, as with a service account running as deploy that should connect as app. You can stay with peer, which needs no password at all, using a map. In pg_ident.conf:
# MAPNAME SYSTEM-USERNAME PG-USERNAMEappmap deploy appAnd in pg_hba.conf:
local shop app peer map=appmapReload as before. It’s a clean setup for scripts on the same machine, with no password stored in any file.
5. Docker and the other engines’ defaults
The official Docker image is set up differently, with trust on the local socket inside the container, and scram-sha-256 from elsewhere:
docker exec -it db psql -U postgresOn RHEL, fresh installs use peer on the socket and ident over TCP. That second one gives a similar message:
FATAL: Ident authentication failed for user "app"Change it to scram-sha-256 in the host lines the same way, and reload. On managed services such as RDS, you don’t get peer at all, as you only connect over TCP.
Warning
Don’t change it to trust, even “just for a moment”. trust lets anyone who can reach it connect as any user, including the superuser, with no password. If you’re locked out and need it, limit it to local and undo it right away.
Shell, we have a problem!
Similar, but different: password authentication failed for user means the method here is a password, and yours is wrong: see that article. no pg_hba.conf entry for host means no rule matches at all. Connection refused means the server isn’t reachable: see PostgreSQL connection refused. role "alex" does not exist means you connected without -U, and there’s no such user.
Found this useful? Share it.
Found a mistake? Let us know at contact@ohsudo.com.