Fix lỗi PostgreSQL FATAL: Peer authentication failed for user

beginner🐘 PostgreSQL2026-03-18| Linux (Debian/Ubuntu/RHEL/CentOS), PostgreSQL 12–16, kết nối Unix socket cục bộ

Error Message

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

TL;DR

Mở /etc/postgresql/*/main/pg_hba.conf, đổi phương thức xác thực peer thành md5 (hoặc scram-sha-256 với PostgreSQL 14+), sau đó reload PostgreSQL.

# Trước:
local   all   all   peer

# Sau:
local   all   all   md5
sudo systemctl reload postgresql

Lỗi Gặp Phải

FATAL: Peer authentication failed for user "myapp"

Lỗi này xảy ra khi bạn kết nối vào PostgreSQL qua Unix socket cục bộ mà tên người dùng hệ điều hành không khớp với role PostgreSQL bạn đang yêu cầu. Lưu ý: lỗi này hoàn toàn không liên quan đến mật khẩu sai. Peer auth thậm chí không kiểm tra mật khẩu.

Nguyên Nhân

Về mặt kỹ thuật, pg_hba.conf (host-based authentication) kiểm soát cách xác thực mọi kết nối đến. Phương thức peer hỏi hệ điều hành: "Người dùng hiện tại là ai?" — rồi kiểm tra xem tên đó có khớp với role PostgreSQL được yêu cầu không.

Giả sử bạn đang đăng nhập với tên ubuntu và chạy:

psql -U postgres

PostgreSQL thấy người dùng hệ điều hành là ubuntu, role yêu cầu là postgres. Không khớp — bị từ chối. Hầu hết các cài đặt Debian/Ubuntu mặc định như sau:

local   all   postgres   peer
local   all   all        peer

Ổn cho việc truy cập cấp hệ thống qua sudo -u postgres psql. Nhưng khi ứng dụng kết nối bằng thông tin xác thực riêng, peer auth sẽ bị lỗi.

Cách Sửa

Cách 1: Chuyển sang md5 hoặc scram-sha-256 (Cách Phổ Biến Nhất)

Đầu tiên, tìm file pg_hba.conf:

# Hỏi PostgreSQL trực tiếp:
sudo -u postgres psql -c "SHOW hba_file;"

# Đường dẫn thông thường:
# Debian/Ubuntu: /etc/postgresql/14/main/pg_hba.conf
# RHEL/CentOS:   /var/lib/pgsql/14/data/pg_hba.conf

Mở file và cập nhật các dòng local từ peer sang md5:

sudo nano /etc/postgresql/14/main/pg_hba.conf
# Đổi dòng này:
local   all   all   peer

# Thành dòng này:
local   all   all   md5

Với PostgreSQL 14+, scram-sha-256 là lựa chọn tốt hơn — đây là mã hóa mật khẩu mặc định từ phiên bản đó và mạnh hơn đáng kể so với MD5:

local   all   all   scram-sha-256

Reload để áp dụng mà không ngắt các kết nối đang hoạt động:

sudo systemctl reload postgresql

Một điều nữa: đảm bảo người dùng database thực sự đã có mật khẩu.

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

Cách 2: Kết Nối Bằng Người Dùng Hệ Điều Hành Tương Ứng

Muốn giữ xác thực peer? Thì người dùng hệ điều hành chạy lệnh cần khớp với role PostgreSQL:

# Cho postgres superuser:
sudo -u postgres psql

# Cho người dùng riêng của ứng dụng:
sudo -u myapp psql -d myapp_db

Tiện cho các tác vụ bảo trì một lần. Không dùng được cho kết nối ứng dụng cần tự xác thực.

Cách 3: Giới Hạn Thay Đổi Cho Một Người Dùng Cụ Thể

Thay vì chuyển tất cả sang xác thực mật khẩu, thêm một rule cụ thể phía trên rule mặc định bắt-tất-cả. Các rule trong pg_hba.conf khớp từ trên xuống dưới — rule đầu tiên khớp sẽ thắng.

# pg_hba.conf — các rule cụ thể đặt trước:
local   myapp_db   myapp   md5
local   all        all     peer

Lúc này myapp xác thực bằng mật khẩu với myapp_db, trong khi superuser postgres và mọi thứ khác vẫn dùng peer auth.

Cách 4: Dùng TCP Thay Vì Unix Socket

Đây là cách giải quyết ít hiển nhiên hơn. Kết nối Unix socket tuân theo các rule local trong pg_hba.conf. Kết nối TCP — kể cả đến 127.0.0.1 — tuân theo các rule host, thường mặc định là md5:

psql -h 127.0.0.1 -U myapp -d myapp_db

Xác nhận các dòng host của bạn cho phép xác thực mật khẩu:

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

Tham Khảo Các Phương Thức pg_hba.conf

  • peer — Tên người dùng hệ điều hành phải khớp với role DB. Không kiểm tra mật khẩu. Chỉ dùng cho local socket.
  • md5 — Yêu cầu mật khẩu, lưu dưới dạng hash MD5. Được hỗ trợ rộng rãi trên mọi client.
  • scram-sha-256 — Yêu cầu mật khẩu, hash mạnh hơn. Cần PostgreSQL 10+ trên cả server và client.
  • trust — Không xác thực gì cả. Chỉ dùng cho dev cục bộ — không bao giờ dùng production.
  • reject — Luôn từ chối. Hữu ích để chặn rõ ràng các IP hoặc người dùng cụ thể.

Kiểm Tra Sau Khi Sửa

# Kết nối với tư cách người dùng ứng dụng:
psql -U myapp -d myapp_db

# Bạn sẽ thấy dấu nhắc như:
# myapp_db=>
# Kiểm tra xem người dùng có mật khẩu chưa:
sudo -u postgres psql -c "SELECT usename, passwd IS NOT NULL AS has_password FROM pg_shadow WHERE usename = 'myapp';"
# Xác nhận các rule pg_hba đã được tải đúng:
sudo -u postgres psql -c "SELECT * FROM pg_hba_file_rules;"

Không còn lỗi peer khi kết nối? Bạn đã xong.

Mẹo

Chuyển sang xác thực bằng mật khẩu nghĩa là mọi người dùng database đều cần mật khẩu thực — đừng bỏ qua bước đó. Nếu cần tạo mật khẩu mạnh, ToolCraft's Password Generator chạy hoàn toàn trên trình duyệt mà không gửi gì lên server, điều này rất đáng lưu ý khi tạo thông tin xác thực database.

Ngoài ra: sau khi chỉnh pg_hba.conf, luôn dùng reload thay vì restart. Reload áp dụng cấu hình mới cho các kết nối đến mà không ảnh hưởng đến kết nối hiện có. Restart chỉ cần thiết cho các thay đổi postgresql.conf — và PostgreSQL sẽ thông báo những thay đổi nào yêu cầu restart.

# Reload không gây gián đoạn:
sudo systemctl reload postgresql

# Hoặc từ bên trong psql:
SELECT pg_reload_conf();

Related Error Notes