permission denied for table
The current role does not have the required privilege (SELECT, INSERT, UPDATE, DELETE, or TRUNCATE) on the named table or view. Postgres checks privileges at execution time against the pg_class and pg_namespace ACL entries.
- 1Role has not been granted SELECT or the required DML privilege on the table
- 2Role was granted privileges on an old version of the table but it was dropped and recreated (privileges do not transfer)
- 3Accessing a table through a view where the view's owner lacks the underlying table privilege
- 4Row-level security policy blocks access (raises a different message but same code in some cases)
- 5Schema-level USAGE privilege missing even if table-level SELECT is granted
A role with no privileges attempts to query a table.
CREATE ROLE readonly_user LOGIN PASSWORD 'pass'; CREATE TABLE private_data (secret TEXT); -- As readonly_user: SELECT * FROM private_data; -- triggers 42501
expected output
ERROR: permission denied for table private_data
Fix
Grant the required privilege to the role
WHEN When the role should legitimately have access.
-- Grant SELECT on the specific table: GRANT SELECT ON TABLE private_data TO readonly_user; -- Grant USAGE on the schema too (required for table access): GRANT USAGE ON SCHEMA public TO readonly_user; -- For all future tables in the schema (Postgres 9.0+): ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly_user;
Why this works
Postgres evaluates table access by calling pg_class_aclcheck() which checks the ACL (access control list) stored in pg_class.relacl. GRANT adds an entry to this ACL. Schema USAGE is checked separately via pg_namespace.nspacl; both must pass for the query to proceed.
✕ Grant SUPERUSER to a role to work around permission errors
Superuser bypasses all permission checks including row security; use fine-grained GRANT instead.
Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev