Sửa lỗi PostgreSQL 'FATAL: password authentication failed' cho User

beginner🐘 PostgreSQL2026-03-19| PostgreSQL 12–16, Linux (Ubuntu/Debian/RHEL), macOS, Windows — psql CLI và connection string trong ứng dụng

Error Message

FATAL: password authentication failed for user "your_user"
#postgresql#xác thực#mật khẩu#pg_hba.conf

TL;DR

Bạn gặp lỗi FATAL: password authentication failed for user "your_user". Hãy kiểm tra danh sách này trước khi đào sâu hơn:

  • Sai mật khẩu → đặt lại bằng ALTER USER your_user WITH PASSWORD 'newpassword';
  • Phương thức xác thực trong pg_hba.conf không khớp → căn chỉnh giữa md5scram-sha-256
  • Người dùng chưa đặt mật khẩu → đặt mật khẩu rõ ràng
  • Lỗi đánh máy trong chuỗi kết nối → kiểm tra lại cấu hình ứng dụng của bạn

Điều Gì Đang Thực Sự Xảy Ra

PostgreSQL đã từ chối mật khẩu mà client của bạn gửi đến. Có ba nguyên nhân riêng biệt dẫn đến lỗi này, và mỗi nguyên nhân cần một cách khắc phục khác nhau. Việc blindly đặt lại mật khẩu chỉ giải quyết được một trong số đó — hãy xác định bạn đang gặp trường hợp nào trước.

Nguyên Nhân 1: Mật Khẩu Đơn Giản Là Sai

Nguyên nhân phổ biến nhất. Mật khẩu trong chuỗi kết nối của bạn không khớp với những gì PostgreSQL đã lưu cho người dùng đó. Lỗi này cũng xảy ra sau khi di chuyển server — ví dụ, nếu bạn dùng pg_dumpall để sao lưu roles nhưng sau đó đặt lại mật khẩu thủ công trên server mới trong khi ứng dụng vẫn dùng giá trị cũ trong cấu hình.

Nguyên Nhân 2: Phương Thức Xác Thực Không Khớp trong pg_hba.conf

pg_hba.conf kiểm soát cách mỗi kết nối được xác thực. Nếu file ghi md5 nhưng mật khẩu được lưu dưới dạng scram-sha-256 (mặc định từ PostgreSQL 14), đăng nhập sẽ thất bại dù mật khẩu hoàn toàn đúng. Chiều ngược lại cũng tương tự — sai hướng, cùng một lỗi.

Nguyên Nhân 3: Người Dùng Chưa Có Mật Khẩu Hoặc Không Tồn Tại

Người dùng được tạo bằng CREATE USER myuser; — không có mệnh đề password — không thể xác thực qua các phương thức dựa trên mật khẩu. PostgreSQL trả về cùng một thông báo lỗi mơ hồ này thay vì thứ gì đó như "no password set", điều này gây bực bội nhưng nhất quán.

Các Cách Khắc Phục

1. Đặt Lại Mật Khẩu Người Dùng

Kết nối với tư cách superuser postgres. Trên Linux, cách này thường hoạt động qua peer authentication:

sudo -u postgres psql

Sau đó đặt lại mật khẩu:

ALTER USER your_user WITH PASSWORD 'your_new_password';

Thoát bằng \q và kiểm tra kết nối:

psql -U your_user -h 127.0.0.1 -d your_database -W

Flag -W buộc hiển thị dấu nhắc mật khẩu, xác nhận rằng bạn đang kiểm tra thông tin xác thực thực sự thay vì âm thầm rơi vào peer auth.

2. Sửa Phương Thức Xác Thực trong pg_hba.conf

Trước tiên, tìm vị trí file pg_hba.conf của bạn:

sudo -u postgres psql -c "SHOW hba_file;"

Trên Ubuntu/Debian với PostgreSQL 15, thường là /etc/postgresql/15/main/pg_hba.conf. Mở file và tìm dòng khớp với loại kết nối của bạn:

# TYPE  DATABASE  USER    ADDRESS         METHOD
host    all       all     127.0.0.1/32    md5

Đang dùng PostgreSQL 14+ với cài đặt mặc định? Hash được lưu là scram-sha-256. Thay đổi phương thức cho khớp:

host    all       all     127.0.0.1/32    scram-sha-256

Cần hỗ trợ các client cũ chỉ dùng được md5? Giữ nguyên phương thức là md5 nhưng hash lại mật khẩu theo định dạng md5 một cách tường minh:

-- Chạy với quyền postgres superuser:
SET password_encryption = md5;
ALTER USER your_user WITH PASSWORD 'your_password';

Sau bất kỳ thay đổi nào trong pg_hba.conf, reload PostgreSQL — không cần khởi động lại hoàn toàn:

sudo systemctl reload postgresql

3. Xác Minh Người Dùng Tồn Tại và Đã Có Mật Khẩu

Kiểm tra xem người dùng có tồn tại không:

sudo -u postgres psql -c "\du your_user"

Không có kết quả nghĩa là người dùng không tồn tại. Tạo người dùng mới:

CREATE USER your_user WITH PASSWORD 'your_password';

Đã tồn tại nhưng không chắc mật khẩu đã được lưu chưa? Truy vấn pg_shadow (chỉ dành cho superuser):

SELECT usename, passwd IS NOT NULL AS has_password
FROM pg_shadow
WHERE usename = 'your_user';

Nếu has_password trả về f, hãy chạy lệnh ALTER USER ở trên để đặt mật khẩu.

4. Debug Nhanh: Tạm Thời Dùng Trust Authentication

Không chắc vấn đề là mật khẩu hay phương thức xác thực? Bạn có thể tạm thời bỏ qua kiểm tra mật khẩu cho người dùng của mình trên localhost. Thêm dòng này vào pg_hba.conf phía trên các dòng host hiện có:

host    all       your_user   127.0.0.1/32    trust

Reload và kết nối. Nếu hoạt động được, cấu hình người dùng và database đều ổn — vấn đề hoàn toàn nằm ở mật khẩu hoặc phương thức hash. Xóa dòng này ngay sau khi kiểm tra xong. Trust auth trong môi trường production là lỗ hổng bảo mật nghiêm trọng.

Xác Minh Đã Khắc Phục Thành Công

Kiểm tra với dấu nhắc mật khẩu tường minh:

psql -U your_user -h 127.0.0.1 -d your_database -W

Với kết nối ứng dụng, hãy kiểm tra log của connection pool. PgBouncer, Sequelize và connection layer của Django đều sử dụng thông tin xác thực mới trong lần thử tiếp theo — thường bạn không cần khởi động lại toàn bộ ứng dụng, chỉ cần chờ pool xoay vòng. Nếu bạn lưu chuỗi kết nối trong biến môi trường, hãy xác nhận giá trị đã cập nhật thực sự được nạp vào tiến trình đang chạy, không chỉ được ghi xuống đĩa.

Bạn cũng có thể kiểm tra trực tiếp từ môi trường của ứng dụng:

psql "postgresql://your_user:your_password@127.0.0.1:5432/your_database"

Mẹo Để Phòng Tránh Lỗi Này

Nguyên nhân tái diễn phổ biến nhất trong môi trường team: ai đó đặt mật khẩu database một lần, không ghi lại tài liệu, và sau đó một developer khác lấy từ Slack hoặc wiki — lỗi đánh máy xảy ra, giá trị dần lỗi thời. Hãy đặt mật khẩu ngẫu nhiên mạnh ngay từ đầu và lưu trữ trong secrets manager hoặc file .env được gitignore, không phải trong chat.

Cần một mật khẩu ngẫu nhiên ngay bây giờ? ToolCraft's Password Generator chạy hoàn toàn trên trình duyệt của bạn mà không xử lý phía server — hữu ích khi bạn muốn thứ gì đó thực sự ngẫu nhiên mà không cần cài đặt gì thêm.

Một điều nữa cần lưu ý sau khi nâng cấp phiên bản lớn: chuyển từ PostgreSQL 13 lên 16 thay đổi password_encryption mặc định từ md5 sang scram-sha-256. Các hash hiện có được giữ nguyên, nhưng bất kỳ lần đặt lại mật khẩu nào sau khi nâng cấp sẽ dùng định dạng mới. Kết quả là bạn có hỗn hợp các loại hash và đảm bảo xảy ra auth mismatch cho người đầu tiên được đặt lại mật khẩu. Hãy kiểm tra toàn bộ sau mỗi lần nâng cấp phiên bản lớn để phát hiện sớm vấn đề này.

Related Error Notes