How to fix Permission denied for table in PostgreSQL

PostgreSQLINTERMEDIATEHIGHUpdated Dec 26, 2025· 297 views

This error occurs when a user lacks the required privileges to access or modify a table. Fix it by granting appropriate permissions using the GRANT statement.

Quick fix

Fixes Permission denied for table

\dp schema_name.table_name
  1. Check current permissions
  2. Grant table privileges
  3. Verify schema USAGE privilege
  4. Grant privileges on related sequences
postgresql — error
\dp schema_name.table_name
Permission denied for table

What this error means

PostgreSQL enforces role-based access control. Each table has an owner and specific privileges that control who can SELECT, INSERT, UPDATE, DELETE, or TRUNCATE the table. When a user attempts an operation without the required privilege, PostgreSQL denies the request with "permission denied for table." This is a critical security feature that prevents unauthorized access to data.

Typical symptoms

  • Queries fail with "ERROR: permission denied for table [table_name]"
  • Only the superuser or table owner can access the table
  • Application connection fails when attempting any SQL operation on the table
  • Different users have different access levels to the same table
  • Batch operations or data imports fail partway through

Common causes

  1. User was not explicitly granted SELECT, INSERT, UPDATE, or DELETE privileges on the table
  2. Privileges were revoked but the user continues to attempt access
  3. User has privileges on the table but not USAGE privilege on the schema containing the table
  4. Privileges were granted before the table was created (grant order matters)
  5. Table ownership changed and default privileges were not updated
  6. Using a service account or application connection with insufficient permissions

How to fix "Permission denied for table"

1Check current permissions

Connect as a superuser or table owner and check who has what permissions:

sql
\dp schema_name.table_name

Or query the information schema:

sql
SELECT grantee, privilege_type
FROM information_schema.role_table_grants
WHERE table_name = 'table_name';

This shows you which roles have which privileges (SELECT, INSERT, UPDATE, DELETE, TRUNCATE, etc.).

2Grant table privileges

Connect as the table owner or a superuser and grant the necessary privileges:

For SELECT only:

sql
GRANT SELECT ON table_name TO username;

For full access:

sql
GRANT ALL PRIVILEGES ON table_name TO username;

For specific operations:

sql
GRANT SELECT, INSERT, UPDATE ON table_name TO username;

Replace table_name with your actual table name and username with the role that needs access.

3Verify schema USAGE privilege

The user must also have USAGE privilege on the schema containing the table, otherwise they still cannot access it:

sql
GRANT USAGE ON SCHEMA schema_name TO username;

For the public schema:

sql
GRANT USAGE ON SCHEMA public TO username;

Without USAGE on the schema, users cannot "see" or access any tables within it, regardless of table-level permissions.

4Grant privileges on related sequences

If the table has an auto-incrementing column (SERIAL or IDENTITY), also grant privileges on the underlying sequence:

sql
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA schema_name TO username;

Otherwise, INSERT operations will fail with "permission denied for sequence."

5Set default privileges for future tables

To automatically grant privileges to this user on all future tables created in the schema, use ALTER DEFAULT PRIVILEGES:

sql
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO username;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO username;

This prevents the same permission issues from occurring when new tables are created.

6Test the fix

Switch to the user account (or test with their connection string) and verify the query now works:

sql
SELECT * FROM table_name LIMIT 1;

If you still get permission denied, double-check that all three requirements are met: (1) table privileges granted, (2) schema USAGE granted, (3) sequence privileges granted (if applicable).

Advanced notes

For cloud-managed PostgreSQL (AWS RDS, Google Cloud SQL, Azure Database), the postgres superuser may not automatically inherit permissions from tables created by other users. You must explicitly grant access. PostgreSQL 15+ restricts public schema access more strictly—only the database owner can create objects in public by default. If you get "permission denied for schema public," grant CREATE and USAGE on the public schema first. For read-only users, revoke all then selectively grant only SELECT: REVOKE ALL ON DATABASE dbname FROM readonly_user; GRANT CONNECT ON DATABASE dbname TO readonly_user; GRANT USAGE ON SCHEMA public TO readonly_user; GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_user; AWS Database Migration Service (DMS) remnants can cause spurious permission errors—check for and remove awsdms_apply_exceptions and related audit triggers if present.

Frequently asked questions

What does "Permission denied for table" mean?
PostgreSQL enforces role-based access control. Each table has an owner and specific privileges that control who can SELECT, INSERT, UPDATE, DELETE, or TRUNCATE the table. " This is a critical security feature that prevents unauthorized access to data.
How do I fix "Permission denied for table"?
This error occurs when a user lacks the required privileges to access or modify a table. Fix it by granting appropriate permissions using the GRANT statement.
What causes "Permission denied for table"?
User was not explicitly granted SELECT, INSERT, UPDATE, or DELETE privileges on the table Privileges were revoked but the user continues to attempt access User has privileges on the table but not USAGE privilege on the schema containing the table
Is the "Permission denied for table" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading