#Что означает ошибка
SQLSTATE 42501 permission denied for schema public означает нехватку прав на действие в схеме public. Начиная с PostgreSQL 15 создание объектов в public по умолчанию устроено строже, чем в некоторых старых установках. Нужны разные права: USAGE — для обращения к объектам схемы, CREATE — для создания новых; обычному приложению не следует давать CREATE без доказанной необходимости.
#Как различить причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| У роли нет CREATEКоманда CREATE TABLE public.x выполняется от роли приложения, которой разрешено читать, но не создавать объекты. | has_schema_privilege(...,'CREATE') возвращает false, ошибка на миграции. | Миграции выполняет отдельная ограниченная роль, приложения обычно нужен только USAGE. |
| У роли нет USAGEСхема существует, но политика доступа отозвала право использования. | has_schema_privilege(...,'USAGE') возвращает false; ошибки на обращении к функциям/объектам схемы. | Владелец схемы адресно выдаёт USAGE только нужной роли. |
| Подключились не под той рольюВ сценарии подключения использован другой пользователь или SET ROLE. | SELECT current_user отличается от ожидаемого. | Исправить учётные данные приложения и роль подключения, а не права всей схемы. |
#Пошаговая диагностика и устранение
- Запишите действие и ошибку 42501В журнале приложения или Query Tool скопируйте SQL, который вызвал
permission denied for schema public, и SQLSTATE 42501. Отметьте, был ли это CREATE TABLE, обращение к существующей таблице или функция. Не пытайтесь исправлять ошибку командамиGRANT ALL ... TO PUBLIC— они открывают доступ гораздо шире, чем требуется. - Проверьте фактическую роль и серверВ psql откройте
\conninfoлибо в pgAdmin выберите нужную базу. ВыполнитеSELECT current_database(), session_user, current_user; SHOW server_version;. Результат покажет, кто подключился и от чьего имени действует текущий запрос. Если роль неожиданная, исправляйте строку подключения на стороне приложения после проверки, а не выдавайте ей дополнительные права. - Разделите USAGE и CREATEВыполните команду
SELECT has_schema_privilege(current_user,'public','USAGE'), has_schema_privilege(current_user,'public','CREATE');. Значение false означает, что соответствующего права нет именно у текущей роли. Если запрос сам возвращает ошибку, запишите её: возможно, подключение не соответствует ожиданиям или схема переименована. - Уточните владельца и назначение схемыВ pgAdmin раскройте Databases → ваша база → Schemas → public → Properties и посмотрите владельца, если пункт доступен в вашей версии; или выполните запрос к pg_namespace. Разберите, нужно ли приложению вообще создавать таблицы: типовой веб-пользователь должен лишь читать и изменять уже существующие данные в рамках своих полномочий.
- Если достаточно USAGE — запросите минимальное разрешениеПередайте владельцу схемы точное имя роли и результат проверки. Владелец либо администратор может выполнить
GRANT USAGE ON SCHEMA public TO app_reader;, где app_reader — реальная согласованная роль. Это право на вход в схему, а не на её таблицы; доступ к конкретным таблицам и функциям выдаётся отдельно. После выполнения повторите тест от имени приложения. - Если ошибка при создании таблиц — отделите миграцииКогда приложение выполняет CREATE TABLE на запуске, перенесите этот этап в отдельную миграцию, запускаемую ролью с согласованным CREATE в предназначенной для этого схеме. Если политика требует public, владелец может выдать
GRANT CREATE ON SCHEMA public TO app_migrator;, но не обычной веб-роли. Не открывайте создание объектов для PUBLIC. - Проверьте таблицы и права отдельноЕсли USAGE на схему появилось, но запрос выдаёт
permission denied for table, это другая ступень доступа. Владелец данных должен выдать адресные SELECT/INSERT/UPDATE/DELETE только для необходимых таблиц и операций. Не ставьте BYPASSRLS и не делайте пользователя superuser. Сверьте после этого ровно ту операцию, которая прежде не выполнялась. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
- Проверьте результат и способ отменыИз приложения повторите безопасное чтение или тестовую миграцию в отдельной базе под нужной ролью. Ещё раз выполните has_schema_privilege и убедитесь, что приложение не получило лишний CREATE. Если выдача прав была ошибочной, владелец может адресно выполнить
REVOKE USAGE ON SCHEMA public FROM app_reader;или аналогичное REVOKE CREATE; сначала убедитесь, что это не нарушит остальные сервисы.
#Воспроизведение и проверка только в отдельной тестовой базе
SELECT current_user, has_schema_privilege(current_user,'public','USAGE') AS use_ok, has_schema_privilege(current_user,'public','CREATE') AS create_ok;#Как убедиться в исправлении и что делать дальше
Ошибочная операция теперь проходит, а проверка USAGE/CREATE соответствует требованиям принципа наименьших прав. При новой ошибке permission denied for table не повторяйте GRANT на схему: выясните владельца и права конкретного объекта. Если исправление не помогло, предоставьте SQLSTATE, current_user, имена объекта и результат has_schema_privilege владельцу БД.