psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: Peer authentication failed for user "postgres"
— on Ubuntu, and so in WSL, a local psql connection logs in by peer
authentication: the server asks the operating system who you are, and you are not the
Linux user postgres. Run psql as that user, sudo -u postgres psql,
and you are in.
If you want to stay yourself and still log in as postgres, give the role a
password and connect over TCP with -h localhost, which the same file
authenticates by password instead of peer. Or create a database role with your own Linux
user name, and a plain psql works.
The error
$ psql -U postgres
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: Peer authentication failed for user "postgres"
A plain psql by the same user failed differently, with
FATAL: role "dev" does not exist: peer looked for a role named after the
Linux user, and there was none yet.
Why it happens
Without -h, psql connects through the Unix socket in
/var/run/postgresql, and Ubuntu's pg_hba.conf says
peer for every socket connection. Peer means the server reads the client's
operating system user from the kernel and accepts only the database role with the same
name. The server log spells it out, including the line that matched:
LOG: provided user name (postgres) and authenticated user name (dev) do not match
FATAL: Peer authentication failed for user "postgres"
DETAIL: Connection matched file "/etc/postgresql/16/main/pg_hba.conf" line 118: "local all postgres peer"
Those are the lines from the real file on the test system, with its own warning above the first one:
# DO NOT DISABLE!
# If you change this first entry you will need to make sure that the
# database superuser can access the database using some other method.
# Noninteractive access to all databases is required during automatic
# maintenance (custom daily cronjobs, replication, and similar tasks).
#
# Database administrative login by Unix domain socket
local all postgres peer
...
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 scram-sha-256
A Docker container does not show this error. The official postgres:18 image's
rules read trust for local socket connections and
scram-sha-256 for TCP from outside, so docker exec into it with
psql -U postgres gets in without a password.
The fix
$ sudo -u postgres psql -c 'SELECT current_user, version();'
current_user | version
--------------+-----------------------------------------------------------
postgres | PostgreSQL 16.15 (Ubuntu 16.15-0ubuntu0.24.04.1) on x86_64-pc-linux-gnu, ...
(1 row)
To log in as postgres from your own account, set a password and use TCP. This
test's cluster listened on port 15201, because Windows' own PostgreSQL holds 5432 on this
PC; on the default port, leave out -p.
$ sudo -u postgres psql -p 15201 -c "ALTER USER postgres PASSWORD 'Fix6TestOnly';"
ALTER ROLE
$ PGPASSWORD=Fix6TestOnly psql -h localhost -p 15201 -U postgres -c 'SELECT current_user, inet_server_addr();'
current_user | inet_server_addr
--------------+------------------
postgres | 127.0.0.1
(1 row)
The third route keeps peer and gives your Linux user a role of its own. On a development box only, a superuser is convenient:
$ sudo -u postgres createuser -p 15201 --superuser dev
$ sudo -u postgres createdb -p 15201 -O dev dev
$ psql -p 15201 -c 'SELECT current_user, current_database();'
current_user | current_database
--------------+------------------
dev | dev
(1 row)
Leave the local all postgres peer line alone, as its comment asks.
How it was reproduced
A throwaway distribution, wsl --install Ubuntu-24.04 --name fix6-pg --no-launch
(Ubuntu 24.04.5, WSL 2.7.10), with a fictional default user dev and
apt-get install postgresql, which gave PostgreSQL 16.15
(16.15-0ubuntu0.24.04.1). The cluster was made with pg_createcluster 16 main,
whose initdb line shows --auth-local peer --auth-host scram-sha-256. The error
was captured on the default socket for port 5432 with TCP switched off; the TCP fixes ran
after the cluster moved to 15201. The names fix6-pg and dev and the password are this
test's own, and the distribution was unregistered afterwards. The container comparison used
postgres:18 (PostgreSQL 18.4).
Frequently asked
- What does 'Peer authentication failed for user postgres' mean?
- psql connected through the local Unix socket, where Ubuntu's pg_hba.conf uses peer authentication. The server takes your operating system user name from the kernel and only allows the database role with the same name, so a Linux user other than postgres cannot log in as postgres that way.
- How do I log in to PostgreSQL as postgres on Ubuntu or WSL?
- Run sudo -u postgres psql, which starts psql as the Linux user postgres so the names match. To log in as postgres from your own account, give the role a password and connect over TCP with psql -h localhost -U postgres.
- Should I change peer in pg_hba.conf to fix it?
- Not on the postgres line. The file's own comment says not to disable it, because maintenance jobs that run as the postgres user rely on it. Use sudo -u postgres, a password over TCP, or a role named after your Linux user instead.
More decoded errors in the Fixes category. If your own user name is the one missing, see FATAL: role does not exist.