How to fix Permission denied for table in PostgreSQL
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- Check current permissions
- Grant table privileges
- Verify schema USAGE privilege
- Grant privileges on related sequences
\dp schema_name.table_namePermission 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
- 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
- Privileges were granted before the table was created (grant order matters)
- Table ownership changed and default privileges were not updated
- Using a service account or application connection with insufficient permissions
How to fix "Permission denied for table"
Connect as a superuser or table owner and check who has what permissions:
\dp schema_name.table_nameOr query the information schema:
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.).
Connect as the table owner or a superuser and grant the necessary privileges:
For SELECT only:
GRANT SELECT ON table_name TO username;For full access:
GRANT ALL PRIVILEGES ON table_name TO username;For specific operations:
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.
The user must also have USAGE privilege on the schema containing the table, otherwise they still cannot access it:
GRANT USAGE ON SCHEMA schema_name TO username;For the public schema:
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.
If the table has an auto-incrementing column (SERIAL or IDENTITY), also grant privileges on the underlying sequence:
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA schema_name TO username;Otherwise, INSERT operations will fail with "permission denied for sequence."
To automatically grant privileges to this user on all future tables created in the schema, use ALTER DEFAULT PRIVILEGES:
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.
Switch to the user account (or test with their connection string) and verify the query now works:
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
- 📚PostgreSQL Official Documentation
- 📖PostgreSQL Docs - GRANT Statement(Official Docs)