- データベース
permission denied for schema publicの直し方
ERROR: permission denied for schema public は、public スキーマにテーブルを作る権限(CREATE)が無いユーザーで、テーブルを作ろうとしたときのエラーです。 PostgreSQL 15 から、一般のユーザーは public にテーブルを作れなくなりました(それまでは誰でも作れた)。
以前の版で動いていた構築の手順・マイグレーションが、15 以降の新しい DB で止まるのが典型です。直し方は3つあります。
| 直し方 | 書き方 | 向いている場面 |
|---|---|---|
| アプリ用の DB を作り、所有者をアプリのユーザーにする | CREATE DATABASE appdb OWNER app8; |
アプリ専用の DB(おすすめ) |
| アプリ用のスキーマを作る | CREATE SCHEMA app AUTHORIZATION app8; |
1つの DB を複数のアプリ・ユーザーで使う |
| public に CREATE を与える | GRANT CREATE ON SCHEMA public TO app8; |
以前の版と同じ動きにしたい |
確認環境:PostgreSQL 16.15(確認日 2026年10月11日)。スーパーユーザー(postgres)が作った DB に、一般のユーザー app8 で接続して再現しました。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「permission denied for schema publicの直し方」
再現
$ psql -h localhost -U app8 -d s8db
=> CREATE TABLE t1 (id int);
ERROR: permission denied for schema public
LINE 1: CREATE TABLE t1 (id int);
SELECT nspname, nspowner::regrole, nspacl FROM pg_namespace WHERE nspname = 'public';
nspname | nspowner | nspacl
---------+-------------------+------------------------------------------
public | pg_database_owner | {pg_database_owner=UC/pg_database_owner,=U/pg_database_owner}
| 権限の表示 | 意味 |
|---|---|
pg_database_owner=UC |
DB の所有者は、使う(U)・作る(C)の両方ができる |
=U(名前が空=全員) |
全員は、使う(U)だけ。作る(C)はできない |
SELECT has_schema_privilege('app8', 'public', 'CREATE'), -- f
has_schema_privilege('app8', 'public', 'USAGE'); -- t
PostgreSQL 15 のリリースノートでは、public スキーマから全員の CREATE 権限を外し、所有者を pg_database_owner(その DB の所有者)に変えたとされています。15 以降に新しく作った DB で起きます。以前の版から移行した DB は、以前の権限のままです。
直し方1:アプリ用の DB を作り、所有者にする(おすすめ)
-- スーパーユーザーで
CREATE DATABASE s8own OWNER app8;
$ psql -h localhost -U app8 -d s8own
=> CREATE TABLE t5 (id int); -- 作れた
DB の所有者は、public スキーマにも CREATE できました(public の所有者が「DB の所有者」のため)。アプリごとに DB を分けるなら、これが一番簡単です。既存の DB なら ALTER DATABASE s8db OWNER TO app8; でも同じになりますが、DB の所有者は DB 全体の管理ができるので、ほかの用途と共用している DB では避けます。
直し方2:アプリ用のスキーマを作る
-- スーパーユーザー(または DB の所有者)で
CREATE SCHEMA app AUTHORIZATION app8;
ALTER ROLE app8 IN DATABASE s8db SET search_path = app, public;
$ psql -h localhost -U app8 -d s8db
=> CREATE TABLE t3 (id int); -- app スキーマに作られた
=> SELECT current_schema(); -- app
スキーマの所有者は、その中にテーブルを作れました。 search_path を設定すると、スキーマ名を付けずに書いた SQL も、app スキーマに作られました。公式ドキュメントでも、ユーザーごとのスキーマを作る使い方が、安全な使い方として説明されています。スキーマと search_path の関係は、関連記事の「PostgreSQL relation does not existの原因と直し方」で扱っています。
直し方3:public に CREATE を与える
GRANT CREATE ON SCHEMA public TO app8;
以前の版と同じく、public にテーブルを作れるようになりました。 リリースノートでも、内部の利用者を警戒する必要が無い新しい DB なら、CREATE を与えれば以前と同じ動きになるとされています。全員(PUBLIC)に与える GRANT CREATE ON SCHEMA public TO PUBLIC は、誰でもテーブルや関数を置ける状態に戻るので、必要なユーザーにだけ与えます。
テーブルを作れたあとの、別の権限エラー
別のユーザー(読み取り用の rd8)で読むと、また別のエラーになりました。
| 状況 | エラー | 直し方 |
|---|---|---|
| public のテーブル t1 を読む | permission denied for table t1 |
GRANT SELECT ON t1 TO rd8; |
| app スキーマのテーブルを読む | permission denied for schema app |
GRANT USAGE ON SCHEMA app TO rd8; |
| 両方を与えたあと | 読めた | — |
| その後に作ったテーブル | 読めない | ALTER DEFAULT PRIVILEGES |
-- app8 で実行:これから app8 が app スキーマに作るテーブルは、rd8 が読める
GRANT USAGE ON SCHEMA app TO rd8;
GRANT SELECT ON ALL TABLES IN SCHEMA app TO rd8; -- 今あるテーブル
ALTER DEFAULT PRIVILEGES IN SCHEMA app GRANT SELECT ON TABLES TO rd8; -- これから作るテーブル
GRANT SELECT ON ALL TABLES は、今あるテーブルだけが対象です。 確認環境でも、ALTER DEFAULT PRIVILEGES のあとに作った app.t4 を rd8 で読めました。公式ドキュメントでは、ALTER DEFAULT PRIVILEGES は実行したユーザーが作るテーブルに効くとされています(別のユーザーが作るなら FOR ROLE を付ける)。
エラーの見分け方
| エラー | 足りない権限 |
|---|---|
permission denied for schema public(CREATE TABLE のとき) |
スキーマへの CREATE |
permission denied for schema app(SELECT のとき) |
スキーマへの USAGE |
permission denied for table t1 |
テーブルへの SELECT・INSERT など |
relation "t1" does not exist |
権限ではなく、テーブルが見つからない(スキーマ・名前の問題) |
確認の手順(チェックリスト)
| 順番 | 確認すること | 方法 |
|---|---|---|
| 1 | PostgreSQL の版 | SHOW server_version;(15 以降か) |
| 2 | public の権限 | pg_namespace の nspacl、has_schema_privilege |
| 3 | DB の所有者は誰か | \l |
| 4 | 直し方を選ぶ | DB の所有者・専用のスキーマ・GRANT CREATE |
| 5 | 読む側のユーザー | スキーマの USAGE、テーブルの SELECT |
| 6 | これから作るテーブル | ALTER DEFAULT PRIVILEGES |
よくある質問
Q. 以前の版から pg_upgrade・ダンプの復元をした DB でも出ますか。 A. リリースノートでは、アップグレードやダンプの復元では public の権限は以前のまま保たれるとされています。新しく作った DB で、同じ手順を流したときに出ます。
まとめ
- public にテーブルを作る権限が無いエラー。PostgreSQL 15 から、一般のユーザーは作れない
- public の所有者は「DB の所有者」。全員は使う(USAGE)だけ
- 直し方は DB の所有者にする(おすすめ)、専用のスキーマ、GRANT CREATE
- 全員への
GRANT CREATE ... TO PUBLICは避ける - 作れたあとは、読む側のユーザーに USAGE・SELECT と
ALTER DEFAULT PRIVILEGES
参考・出典
確認日はいずれも 2026年10月11日です。
- PostgreSQL「Release 15」:https://www.postgresql.org/docs/release/15.0/
- PostgreSQL 16 Documentation「Schemas」:https://www.postgresql.org/docs/16/ddl-schemas.html
- PostgreSQL 16 Documentation「ALTER DEFAULT PRIVILEGES」:https://www.postgresql.org/docs/16/sql-alterdefaultprivileges.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「permission denied for schema publicの直し方」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。