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.
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.
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).
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.
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL
ERROR 42501: must be owner of table
How to fix "must be owner of table" in PostgreSQL
trigger cannot change partition destination
How to fix "Trigger cannot change partition destination" in PostgreSQL
SSL error: certificate does not match host name
SSL error: certificate does not match host name in PostgreSQL
No SSL connection
No SSL connection to PostgreSQL