できない.dev

PostgreSQL で「role does not exist」になり接続・操作できない

FATAL: role ... does not exist は、接続に使うロール(ユーザー)がそのクラスタに無いときに出る。
CREATE ROLE で作るか、接続ユーザー名や POSTGRES_USER を実在するロールに合わせれば解消する。

公開: 更新:

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

要約

FATAL: role "app" does not exist(psql: ... role ... does not exist)は、接続しようとしたロール(PostgreSQL ではユーザー=ロール)がそのデータベースクラスタに登録されていないときに出る。
ロールはデータベース単位ではなくクラスタ全体で共有されるため(Database Roles(新しいタブで開く))、どこかで作っておく必要がある。
まず実在するロールを確認し、無ければ作る。
名前がずれているだけなら接続情報を直す。

実行例

-U を省いて psql を実行すると OS ユーザー名と同じ root ロールを探して FATAL: role "root" does not exist になり、作っていない app を指定した場合も同じエラーで、どちらも終了コード 2 で接続できなかった。postgres で接続して pg_roles を見ると pg_ で始まる定義済みロール以外は postgres しかなく、CREATE ROLE で LOGIN 付きの app を作ったあとは app で接続でき、current_user に app が返っている。

$ whoami
root
$ psql -d postgres -f whoami.sql
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  role "root" does not exist
$ echo $?
2
$ psql -U app -d postgres -f whoami.sql
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  role "app" does not exist
$ echo $?
2
$ psql -U postgres -a -f list_roles.sql
SELECT rolname FROM pg_roles ORDER BY 1;
           rolname           
-----------------------------
 pg_checkpoint
 pg_create_subscription
 pg_database_owner
 pg_execute_server_program
 pg_maintain
 pg_monitor
 pg_read_all_data
 pg_read_all_settings
 pg_read_all_stats
 pg_read_server_files
 pg_signal_backend
 pg_stat_scan_tables
 pg_use_reserved_connections
 pg_write_all_data
 pg_write_server_files
 postgres
(16 rows)
$ psql -U postgres -a -f create_role.sql
CREATE ROLE app WITH LOGIN PASSWORD 'secret';
CREATE ROLE
SELECT rolname, rolcanlogin FROM pg_roles WHERE rolname = 'app';
 rolname | rolcanlogin 
---------+-------------
 app     | t
(1 row)
$ psql -U app -d postgres -f whoami.sql
current_user 
--------------
 app
(1 row)
$ echo $?
0

— 2026-09-14 時点の出力

検証環境

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

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

よくある原因

  1. 未作成: ロールを一度も作っていない。
    単純な綴り違いも含む。
  2. 既定ロールの思い込み: psql はユーザー名を省くと OS ユーザー名と同じロールを探すので、エラーには OS ユーザー名がそのまま出る(root で実行すれば role "root" does not exist)。
    逆に initdb は、実行した OS ユーザーの名前でスーパーユーザーを作る。postgres 以外のユーザーで初期化したクラスタでは postgres ロールが無く、-U postgres で接続すると「role "postgres" does not exist」になる。
  3. Docker の後出し変更: POSTGRES_USER を変更しても、既に作られたデータボリュームには反映されず旧ロールしか存在しない。
  4. 削除・別クラスタ: 誤って削除した、または別インスタンスに作ってしまった。

解決策

1. ロールを作成する

スーパーユーザー(多くは postgres)で接続して作る(CREATE ROLE(新しいタブで開く))。

CREATE ROLE app WITH LOGIN PASSWORD 'secret';

LOGIN を付けないと接続用にならない点に注意。CREATE USER は LOGIN 付きの別名。

2. 実在するロールを確認する

SELECT rolname FROM pg_roles ORDER BY 1;

ここに出ない名前で接続していれば、それが原因。psql なら \du でも一覧できる。

3. 接続情報を合わせる / Docker を作り直す

アプリの user や PGUSER を実在ロールに合わせる。
Docker で初期ユーザーを変えたいときは、データボリュームを消してから再作成する。

docker compose down -v   # ボリュームごと削除(データも消える点に注意)
docker compose up -d

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