Fix PostgreSQL FATAL: Peer authentication failed for user

beginner๐Ÿ˜ PostgreSQL2026-03-18| Linux (Debian/Ubuntu/RHEL/CentOS), PostgreSQL 12โ€“16, local Unix socket connections

Error Message

FATAL: Peer authentication failed for user
#postgresql#auth#pg_hba#peer

TL;DR

Open /etc/postgresql/*/main/pg_hba.conf, change the peer authentication method to md5 (or scram-sha-256 for PostgreSQL 14+), then reload PostgreSQL.

# Before:
local   all   all   peer

# After:
local   all   all   md5
sudo systemctl reload postgresql

The Error

FATAL: Peer authentication failed for user "myapp"

You'll hit this when connecting to PostgreSQL over a local Unix socket while your OS username doesn't match the PostgreSQL role you're requesting. Worth noting: this has nothing to do with a wrong password. Peer auth never even checks one.

Root Cause

Under the hood, pg_hba.conf (host-based authentication) controls how every incoming connection gets authenticated. The peer method asks the OS: "who's the current user?" โ€” then checks if that name matches the requested PostgreSQL role.

Say you're logged in as ubuntu and run:

psql -U postgres

PostgreSQL sees OS user ubuntu, requested role postgres. No match โ€” denied. Most Debian/Ubuntu installs ship with this default:

local   all   postgres   peer
local   all   all        peer

Fine for system-level access via sudo -u postgres psql. But the moment your app connects using its own credentials, peer auth breaks it.

Fix Approaches

Option 1: Switch to md5 or scram-sha-256 (Most Common Fix)

First, locate your pg_hba.conf:

# Ask PostgreSQL directly:
sudo -u postgres psql -c "SHOW hba_file;"

# Typical paths:
# Debian/Ubuntu: /etc/postgresql/14/main/pg_hba.conf
# RHEL/CentOS:   /var/lib/pgsql/14/data/pg_hba.conf

Open the file and update the local lines from peer to md5:

sudo nano /etc/postgresql/14/main/pg_hba.conf
# Change this:
local   all   all   peer

# To this:
local   all   all   md5

On PostgreSQL 14+, scram-sha-256 is the better choice โ€” it became the default password encryption in that version and is significantly stronger than MD5:

local   all   all   scram-sha-256

Reload to apply without dropping active connections:

sudo systemctl reload postgresql

One more thing: make sure the database user actually has a password set.

sudo -u postgres psql
ALTER USER myapp WITH PASSWORD 'your_password_here';
\q

Option 2: Connect as the Matching OS User

Prefer keeping peer auth? Then the OS user running the command needs to match the PostgreSQL role:

# For the postgres superuser:
sudo -u postgres psql

# For an app-specific user:
sudo -u myapp psql -d myapp_db

Handy for one-off maintenance tasks. Useless for application connections that need to authenticate on their own.

Option 3: Scope the Change to a Specific User

Rather than switching everyone to password auth, add a targeted rule above the default catch-all. Rules in pg_hba.conf match top-to-bottom โ€” first match wins.

# pg_hba.conf โ€” specific rules go first:
local   myapp_db   myapp   md5
local   all        all     peer

Now myapp authenticates with a password against myapp_db, while the postgres superuser and everything else keeps peer auth.

Option 4: Use TCP Instead of Unix Socket

Here's a less obvious workaround. Unix socket connections follow the local rules in pg_hba.conf. TCP connections โ€” even to 127.0.0.1 โ€” follow the host rules, which usually default to md5:

psql -h 127.0.0.1 -U myapp -d myapp_db

Confirm your host lines allow password auth:

host   all   all   127.0.0.1/32   md5
host   all   all   ::1/128        md5

pg_hba.conf Method Reference

  • peer โ€” OS username must match DB role. No password checked. Local socket only.
  • md5 โ€” Password required, stored as MD5 hash. Widely supported across all clients.
  • scram-sha-256 โ€” Password required, stronger hashing. Needs PostgreSQL 10+ on both server and client.
  • trust โ€” No authentication at all. Local dev only โ€” never production.
  • reject โ€” Always deny. Useful for explicitly blocking specific IPs or users.

Verify the Fix

# Connect as your app user:
psql -U myapp -d myapp_db

# You should land at a prompt like:
# myapp_db=>
# Check whether the user has a password set:
sudo -u postgres psql -c "SELECT usename, passwd IS NOT NULL AS has_password FROM pg_shadow WHERE usename = 'myapp';"
# Confirm pg_hba rules loaded correctly:
sudo -u postgres psql -c "SELECT * FROM pg_hba_file_rules;"

No peer error on connect? You're done.

Tips

Switching to password-based auth means every database user needs an actual password โ€” don't skip that step. If you need to generate something strong, ToolCraft's Password Generator runs entirely in-browser with nothing sent to a server, which is worth knowing when you're creating database credentials.

Also: after editing pg_hba.conf, always use reload rather than restart. A reload applies the new config to incoming connections without touching existing ones. Restart is only needed for postgresql.conf changes โ€” and PostgreSQL will tell you which ones require it.

# Non-disruptive reload:
sudo systemctl reload postgresql

# Or from inside psql:
SELECT pg_reload_conf();

Related Error Notes