How to fix ERROR: permission denied for schema public (SQLSTATE 42501) in PostgreSQL

PostgreSQLBEGINNERMEDIUMUpdated May 28, 2026· 453 views

Your role lacks USAGE/CREATE on the schema (common in PG15+). Fix with GRANT USAGE, CREATE ON SCHEMA public TO role.

Quick fix

Fixes ERROR: permission denied for schema public (SQLSTATE 42501)

-- Check current user and database:
SELECT current_user, current_database();

-- List all schemas:
\dn
-- or:
SELECT schema_name FROM information_schema.schemata;

-- Check which schema the user is trying to access:
SHOW search_path;  -- Shows the default schema search order
  1. Verify the current user and schema context
  2. Connect to PostgreSQL as a superuser or role with appropriate privileges
  3. Grant USAGE privilege on the schema to the user
  4. Grant CREATE privilege if the user needs to create objects
postgresql — error
-- Check current user and database:
SELECT current_user, current_database();
-- List all schemas:
\dn
-- or:
SELECT schema_name FROM information_schema.schemata;
-- Check which schema the user is trying to access:
SHOW search_path; -- Shows the default schema search order
ERROR: permission denied for schema public (SQLSTATE 42501)

What this error means

PostgreSQL "permission denied for schema" is a privilege error that occurs when the connected user lacks the required permissions to perform operations on a specific schema. Schemas are namespace containers in PostgreSQL that organize tables, views, functions, and other objects. When PostgreSQL encounters a query or operation targeting a schema where the current user does not have the necessary privileges, it immediately fails with this error. The error can occur on schema-level operations like CREATE TABLE, SELECT from existing tables, or even just navigating to objects within that schema. PostgreSQL 15 introduced a significant security change: the default permissions of the public schema were restricted. Before PostgreSQL 15, any user could create objects in the public schema. Starting with version 15, only the database owner can create objects in the public schema without explicit permission grants. This change was made to prevent privilege escalation attacks where malicious users could inject code into the shared public schema. Permission denied errors manifest when users try to create tables, insert data, or even query existing tables without the proper USAGE or CREATE grants on the schema.

Typical symptoms

  • SQL commands fail with "ERROR: permission denied for schema public" or "ERROR: permission denied for schema [schema_name]"
  • CREATE TABLE statements fail immediately for all non-superuser accounts
  • INSERT, UPDATE, DELETE operations fail on existing tables
  • SELECT queries on existing objects fail with permission error
  • Application migrations or ORM operations suddenly fail after PostgreSQL upgrade to 15+
  • ORMs like Prisma, Sequelize, or Django ORM report schema permission errors during initialization
  • New database users cannot create any objects despite having database CONNECT privilege

Common causes

  1. User lacks USAGE privilege on the target schema (cannot access objects within schema)
  2. User lacks CREATE privilege on the target schema (cannot create new objects in schema)
  3. PostgreSQL 15+ has restricted public schema permissions requiring explicit GRANT statements
  4. User account is not the schema owner and was never granted appropriate privileges
  5. Default privileges were not set for new objects created after the user was added
  6. Permissions revoked during a security audit or configuration change without proper restoration
  7. Database role hierarchy not properly configured (user role not in correct role group)

How to fix "ERROR: permission denied for schema public (SQLSTATE 42501)"

1Verify the current user and schema context

First, understand which user is experiencing the error and which schema they need to access. Connect to PostgreSQL as a superuser and check the current state.

sql
-- Check current user and database:
SELECT current_user, current_database();

-- List all schemas:
\dn
-- or:
SELECT schema_name FROM information_schema.schemata;

-- Check which schema the user is trying to access:
SHOW search_path;  -- Shows the default schema search order

Identify the specific schema name (typically "public" for the default schema) that is causing the permission error.

2Connect to PostgreSQL as a superuser or role with appropriate privileges

You must have superuser or schema owner privileges to grant permissions to other users. Connect with a superuser account to make changes.

bash
# Connect as superuser (postgres user is typically the default superuser)
psql -U postgres -d your_database

# Or if using a connection string:
psql postgresql://admin@localhost/your_database

Once connected as a privileged user, you can grant the necessary permissions to the affected user.

3Grant USAGE privilege on the schema to the user

The USAGE privilege allows the user to access objects (tables, views, functions) that exist within the schema. This is the minimum required privilege.

sql
-- Grant USAGE privilege on the public schema:
GRANT USAGE ON SCHEMA public TO your_username;

-- Or for a custom schema:
GRANT USAGE ON SCHEMA your_schema TO your_username;

-- Grant to a role (if the user is part of a role):
GRANT USAGE ON SCHEMA public TO your_role;

After running this command, the user will be able to query existing tables in the schema, but still cannot create new objects.

4Grant CREATE privilege if the user needs to create objects

If the user needs to create new tables, views, functions, or other objects in the schema, grant the CREATE privilege. This is required for migrations and DDL operations.

sql
-- Grant CREATE privilege on the public schema:
GRANT CREATE ON SCHEMA public TO your_username;

-- Grant both USAGE and CREATE together:
GRANT USAGE, CREATE ON SCHEMA public TO your_username;

-- Or grant ALL privileges (USAGE + CREATE + other administrative privileges):
GRANT ALL ON SCHEMA public TO your_username;

The CREATE privilege is essential for ORM migrations (Prisma, Sequelize, etc.) to create tables and indexes.

5Grant table-level privileges on existing objects

Even with schema privileges, users still need explicit permissions on individual tables. Grant appropriate privileges on all existing tables.

sql
-- Grant SELECT, INSERT, UPDATE, DELETE on all existing tables:
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO your_username;

-- Or for read-only access:
GRANT SELECT ON ALL TABLES IN SCHEMA public TO your_username;

-- Grant usage on sequences (required for auto-increment columns):
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO your_username;

-- Grant execute on functions:
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO your_username;

These grants apply to existing objects. For new objects created in the future, use ALTER DEFAULT PRIVILEGES.

6Set default privileges for future objects

Configure default privileges so that new objects automatically inherit the correct permissions without needing to grant them manually each time.

sql
-- As the schema owner or superuser, set defaults:
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO your_username;

ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE ON SEQUENCES TO your_username;

ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT EXECUTE ON FUNCTIONS TO your_username;

These rules automatically apply to objects created after the ALTER DEFAULT PRIVILEGES statement. Existing objects are not affected.

7Verify the permissions were granted correctly

Query the system catalogs to confirm the user now has the necessary privileges.

sql
-- Check schema privileges:
SELECT grantee, privilege_type
FROM information_schema.role_schema_grants
WHERE schema_name = 'public' AND grantee = 'your_username'
ORDER BY privilege_type;

-- Check table privileges:
SELECT grantee, privilege_type
FROM information_schema.role_table_grants
WHERE table_schema = 'public' AND grantee = 'your_username'
ORDER BY table_name, privilege_type;

-- For a comprehensive view of what the user can do:
\dp public.*

Verify that USAGE and CREATE appear in the results for the schema. For tables, verify SELECT, INSERT, UPDATE, DELETE are listed.

8Test the connection with the unprivileged user

Reconnect using the user account that was experiencing the error to verify the fix works.

bash
# Connect as the user that had permission errors:
psql -U your_username -d your_database

Then try the operations that previously failed:

sql
-- Test schema access:
SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';

-- Test creating a table (if CREATE was granted):
CREATE TABLE test_table (id INT, name VARCHAR(100));

-- Test inserting data:
INSERT INTO test_table VALUES (1, 'test');

-- Clean up:
DROP TABLE test_table;

If these commands succeed without permission errors, the issue is resolved.

Advanced notes

For PostgreSQL 15 migrations: if you are upgrading from PostgreSQL 14 or earlier, the breaking change in public schema permissions often catches teams off guard during CI/CD deployments. When running migrations with a non-superuser account, explicitly grant permissions before running migration tools. Many ORMs have built-in superuser checks that temporarily switch to superuser for migrations—check your ORM configuration.

Row-level security (RLS) can also cause permission-like errors. If a user has table-level permissions but RLS policies restrict row access, they will still see permission denied errors. Check for RLS policies using SELECT * FROM pg_policies WHERE tablename = 'your_table'.

For multi-tenant systems, consider using separate schemas per tenant rather than row-level filters. This isolates data more effectively and simplifies permission management.

When using connection pooling (PgBouncer, pgpool), ensure the pooler user has sufficient privileges and that prepared statement parameters are properly handled—some pooling modes restrict privilege escalation during pooled sessions.

Always follow the principle of least privilege: grant only the minimum permissions needed for each user role. Never use superuser credentials in application code. Create dedicated application users with limited schema and table permissions, separate from admin accounts.

Frequently asked questions

What does "ERROR: permission denied for schema public (SQLSTATE 42501)" mean?
PostgreSQL "permission denied for schema" is a privilege error that occurs when the connected user lacks the required permissions to perform operations on a specific schema. Schemas are namespace containers in PostgreSQL that organize tables, views, functions, and other objects. When PostgreSQL encounters a query or operation targeting a schema where the current user does not have the necessary privileges, it immediately fails with this error.
How do I fix "ERROR: permission denied for schema public (SQLSTATE 42501)"?
Your role lacks USAGE/CREATE on the schema (common in PG15+). Fix with GRANT USAGE, CREATE ON SCHEMA public TO role.
What causes "ERROR: permission denied for schema public (SQLSTATE 42501)"?
User lacks USAGE privilege on the target schema (cannot access objects within schema) User lacks CREATE privilege on the target schema (cannot create new objects in schema) PostgreSQL 15+ has restricted public schema permissions requiring explicit GRANT statements
Is the "ERROR: permission denied for schema public (SQLSTATE 42501)" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading