PostgreSQL のパスワード認証失敗:原因と解決策
結論 password authentication failed for user "app" は、原因を意図的に伏せた文言です。実装では、pg_hba.conf の照合方式が password・md5・scram-sha-256 のいずれかであれば、失敗の中身にかかわらずこの1文が返ります。 伏せる理由は実装のコメントに書かれています。パスワードの取得に失敗しても、利用者が存在しないことをクライアントに悟らせないために、認証の手順を最後まで進めるという作りです。したがって、存在しないロール名で接続しても、パスワードを間違えた場合とまったく同じ文言が返ります。 本当の理由は errdetail_log() で出力されており、これはサーバーのログにだけ書かれます。クライアントには届きません。しかも、この詳細には照合に使われた pg_hba.conf の経路と行番号、その行の原文まで含まれています。 つまり最初にすべきことはパスワードの再入力ではなく、サーバーのログを開くことです。 エラーが発生する処理段階 このエラーは接続が成立したあとに出ます。手前の段階はすべて通っています。 まず TCP または Unix ドメインソケットの接続が確立します。ここで拒まれれば connection refused になり、この文言は出ません。次に起動時のやり取りで、データベース名と利用者名がサーバーへ送られます。 続いて pg_hba.conf の照合です。上から順に、接続の種類・データベース・利用者・接続元を見て、最初に一致した行が採用されます。一致する行が1つも無ければ no pg_hba.conf entry for host になります。 一致した行の方式がパスワード系であれば、ここで確認が行われます。失敗するとこの文言が返ります。データベースの存在確認や接続権限の確認は、さらに後の段階です。 最初に確認すること クライアント側の表示には、状態コード以上の情報はありません。 psql: error: connection to server at "db.internal" (10.0.1.5), port 5432 failed: FATAL: password authentication failed for user "app" サーバーのログを開くと、同じ時刻に DETAIL が並んで出ています。 sudo tail -n 50 /var/log/postgresql/postgresql-16-main.log 出力はこの形になります。 FATAL: password authentication failed for user "app" DETAIL: Password does not match for user "app". Connection matched file "/etc/postgresql/16/main/pg_hba.conf" line 96: "host all all 10.0.1.0/24 scram-sha-256" 1行目の DETAIL が本当の理由です。実装で定義されている文言は6種類で、Role "app" does not exist.、User "app" has no password assigned.、User "app" has an expired password.、User "app" has a password that cannot be used with MD5 authentication.、Password does not match for user "app".、Password of user "app" is in unrecognized format. です。どれが出ているかで、次に見る場所が確定します。 ...