F.Ko-Jiの「一秒後は未来」

heroku pg:pull 実行時に「FATAL: Ident authentication failed for user」というエラー

Heroku 上の PostgreSQL データベースのデータをローカルの開発環境の PostgreSQL にダンプしようとしてハマった。

対象のアプリが古くて開発環境では SQLite を使っており、開発環境に PostgreSQL をインストールしたばかりという状況だったので状況としては特殊かもしれない。

症状

heroku pg:pull のコマンドを実行すると pg_restore のところで「FATAL: Ident authentication failed for user」というエラーが出て止まる。

原因

  • 開発環境の PostgreSQL にパスワードなしのユーザーを作成した
  • pgsql コマンドに「-h localhost」をつけた際に認証が失敗する状態になっていた

対処

PostgreSQL/localhostを指定すると接続できない場合の対処方法 – 調べる.db」を参考に pg_hba.conf ファイルの内容を修正。このファイルは /var/lib/pgsql/data/pg_hba.conf にあるが環境によっては /var/lib/pgsql/9.5/data/pg_hba.conf などにある。

具体的には「host all all 127.0.0.1/32 ident」となっている行の「ident」を「trust」に変更する。

# IPv4 local connections:
#host    all             all             127.0.0.1/32            ident
host    all             all             127.0.0.1/32            trust

修正後、保存して postgresql を再起動。

なお CentOS 6 系など IPv6 が有効になっている場合は、「::1/128」の行のほうの「ident」を「trust」に変更するようにします。

調査

heroku pg:pull コマンド実行時のエラー部分のログは以下の通り。

pg_dump: dumping contents of table messages
pg_restore: connecting to database for restore
pg_restore: [archiver (db)] connection to database "mylocaldb" failed: FATAL:  Ident authentication failed for user "vagrant"
pg_restore: mylocaldb aborted because of error
psql: FATAL:  Ident authentication failed for user "vagrant"
 !    Heroku client internal error.
 !    Search for help at: https://help.heroku.com
 !    Or report a bug at: https://github.com/heroku/heroku/issues/new

    Error:       psql failed. exit status 512, output: "" (RuntimeError)
    Command:     heroku pg:pull HEROKU_POSTGRESQL_COBALT mylocaldb --app ***
    Version:     heroku-toolbelt/3.27.1 (x86_64-linux) ruby/1.8.7
    Error ID:    c6be0ded672f41b69bb893e2e4db73cb


    More information in /home/vagrant/.heroku/error.log

認証まわりのエラーというのは見れば分かるのだが、パスワードなしのユーザーなのになぜ認証に失敗しているのか、意味が分からない。

よく見ると最終行に ~/.heroku/error.log に詳細な情報が書きだされているとあったのでそのログを見てみた。ちなみにこの「More information in /home/vagrant/.heroku/error.log」に気づくのに時間がかかった。

.heroku/error.log の内容は以下の通り。

Heroku client internal error.
psql failed. exit status 512, output: ""
/home/vagrant/.heroku/client/lib/heroku/command/pg.rb:617:in `exec_sql_on_uri'
/home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:108:in `send'
/home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:108:in `exec_sql_on_uri'
/home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:89:in `verify_extensions_match'
/home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:28:in `verify'
/home/vagrant/.heroku/client/lib/heroku/helpers/pg_dump_restore.rb:16:in `execute'
/home/vagrant/.heroku/client/lib/heroku/command/pg.rb:359:in `pull'
/home/vagrant/.heroku/client/lib/heroku/command.rb:223:in `send'
/home/vagrant/.heroku/client/lib/heroku/command.rb:223:in `run'
/home/vagrant/.heroku/client/lib/heroku/cli.rb:40:in `start'
/usr/local/heroku/bin/heroku:24

lib/heroku/command/pg.rb の 617 行目でエラーになっている。該当箇所は以下のメソッド。

  def exec_sql_on_uri(sql,uri)
    begin
      ENV["PGPASSWORD"] = uri.password
      ENV["PGSSLMODE"]  = (uri.host == 'localhost' ?  'prefer' : 'require' )
      user_part = uri.user ? "-U #{uri.user}" : ""
      output = `#{psql_cmd} -c "#{sql}" #{user_part} -h #{uri.host} -p #{uri.port || 5432} #{uri.path[1..-1]}`
      if (! $?.success?) || output.nil? || output.empty?
        raise "psql failed. exit status #{$?.to_i}, output: #{output.inspect}"
      end
      output
    rescue Errno::ENOENT
      output_with_bang "The local psql command could not be located"
      output_with_bang "For help installing psql, see https://devcenter.heroku.com/articles/heroku-postgresql#local-setup"
      abort
    end
  end

変数 output に実行結果を格納しているコマンドが原因っぽいので、そのコマンドを出力してみると以下のようなものだった。

"command psql -c \"SELECT extname FROM pg_extension ORDER BY extname;\"  -h localhost -p 5432 mylocaldb"

このコマンドをシェル上で直接実行してみると、

$ psql -c "SELECT extname FROM pg_extension ORDER BY extname;"  -h localhost -p 5432 mylocaldb
psql: FATAL:  Ident authentication failed for user "vagrant"

確かにエラー。PostgreSQL の認証エラーについて色々調べてるときに -h localhost をつけるつけないといった話があったので試しに外して実行してみると、

$ psql -c "SELECT extname FROM pg_extension ORDER BY extname;" -p 5432 mylocaldb
 extname 
---------
 plpgsql
(1 row)

エラーにならない!というわけで原因が判明した。。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

著者について

fkoji

F.Ko-Ji

Webエンジニアやってます。最近は ドットインストール の開発がお仕事です。その傍ら、個人で Meity電車遅延なう梅酒.in#グラドル自画撮り部 の部室といったネットサービスを開発・運営してます。梅酒と草野球とリアル脱出ゲームが好きです。

» 詳しいプロフィールや運営サービスの一覧など