できない.dev

PostgreSQL で「password authentication failed for user」になり接続できない

psql や ORM の接続で FATAL: password authentication failed が出るのは、パスワード不一致か pg_hba.conf の認証方式の食い違いが原因。
ロールのパスワード再設定と pg_hba.conf の方式確認+reload で解消する。

公開: 更新:

実行例あり(2026-09-19 に実環境で検証)

要約

psql: error: ... FATAL: password authentication failed for user "app" は、サーバーが受け取ったパスワードがロールの保存値と一致しないときに出る。
原因はパスワードの単純な間違いか、pg_hba.conf の認証方式とハッシュ方式の食い違いのどちらか。
まずロールのパスワードを再設定し、それでも通らなければ pg_hba.conf の該当行と password_encryption を確認する。

実行例

環境変数 PGPASSWORD に古いパスワードが残っていると FATAL: password authentication failed で終了コード 2 になり、接続 URL に正しいパスワードを直接書けば通る。
pg_hba.conf が scram-sha-256 を要求しているのに pg_authid のハッシュが md5 のままだと正しいパスワードでも弾かれ、ALTER ROLE で設定し直してハッシュが SCRAM-SHA-256 に変わったところで接続できた。

$ psql -h localhost -U app -d appdb -c "SELECT current_user;"
psql: error: connection to server at "localhost" (::1), port 5432 failed: FATAL:  password authentication failed for user "app"
$ echo $?
2
$ echo "$PGPASSWORD"
old-password
$ psql "postgresql://app:new-secure-password@localhost:5432/appdb" -c "SELECT current_user;"
current_user 
--------------
 app
(1 row)
$ echo $?
0
$ psql "postgresql://app:new-secure-password@localhost:5432/appdb" -c "SELECT current_user;"
psql: error: connection to server at "localhost" (::1), port 5432 failed: FATAL:  password authentication failed for user "app"
$ echo $?
2
$ grep -E '^host +all +all +(127.0.0.1/32|::1/128)' "$(psql -U postgres -Atc 'SHOW hba_file;')"
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256
$ psql -U postgres -c "SELECT rolname, left(rolpassword, 13) AS hash_prefix FROM pg_authid WHERE rolname = 'app';"
rolname |  hash_prefix  
---------+---------------
 app     | md59097d2a199
(1 row)
$ psql -U postgres -c "SHOW password_encryption;" -c "ALTER ROLE app WITH PASSWORD 'new-secure-password';" -c "SELECT rolname, left(rolpassword, 13) AS hash_prefix FROM pg_authid WHERE rolname = 'app';"
password_encryption 
---------------------
 scram-sha-256
(1 row)
 
ALTER ROLE
 rolname |  hash_prefix  
---------+---------------
 app     | SCRAM-SHA-256
(1 row)
$ psql "postgresql://app:new-secure-password@localhost:5432/appdb" -c "SELECT current_user;"
current_user 
--------------
 app
(1 row)
$ echo $?
0

— 2026-09-19 時点の出力

検証環境

検証日
実行環境
postgres:17Debian GNU/Linux 13 (trixie)

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. パスワード不一致: 単純なタイプミスのほか、ロールにそもそもパスワードが設定されていないのに password 認証を要求しているケース。
  2. 認証方式の食い違い: pg_hba.conf の方式が scram-sha-256 なのに、保存されているのが md5 ハッシュ(または逆)で照合できない。
  3. 古い接続情報: シェルの PGPASSWORD やホームの .pgpass、アプリの環境変数が古い値を握っていて、入力したつもりの値が使われていない。
  4. アップグレード起因: メジャーバージョン移行で password_encryption の既定が変わり、移行前ハッシュと不一致になる。

解決策

1. ロールのパスワードを再設定する

スーパーユーザーで接続し、対象ロールのパスワードを設定し直す。

ALTER ROLE app WITH PASSWORD 'new-secure-password';

この時点のサーバー設定(password_encryption)でハッシュが作り直されるため、方式の食い違いも同時に解消されることが多い。

2. pg_hba.conf の認証方式を確認して reload する

接続種別(local / host)ごとに方式が決まる。scram-sha-256 を使う行の例。

# TYPE  DATABASE  USER  ADDRESS         METHOD
host    all       all   127.0.0.1/32    scram-sha-256

編集後は再起動不要で reload するだけでよい(pg_hba.conf のドキュメント(新しいタブで開く))。

SELECT pg_reload_conf();

3. 接続情報を突き合わせる

user・password・host・port・database を一つずつ確認する。
シェル変数が割り込んでいないかも見る。

echo "$PGPASSWORD"
psql "postgresql://app:new-secure-password@localhost:5432/appdb"

この記事は役立ちましたか?