How to Fix “Access Denied” Errors in PostgreSQL

Galaxy Glossary

How do I resolve "permission denied" errors in PostgreSQL?

“Access denied” means the connected role lacks the required privileges on a database object or is blocked by row-level security.

Sign up for the latest in SQL knowledge from the Galaxy Team!
Welcome to the Galaxy, Guardian!
Oops! Something went wrong while submitting the form.

Description

Table of Contents

Why does PostgreSQL say “permission denied”?

PostgreSQL rejects a statement when the current role has no privilege on the target object or when row-level security (RLS) blocks the row. The server stops the query and returns “ERROR: permission denied for …”.

How can I check existing privileges?

Querying the catalog

Run \dp schema.table in psql or query pg_catalog.pg_roles and information_schema.table_privileges to see who owns the object and which roles have SELECT, INSERT, UPDATE, or DELETE.

How do I grant access quickly?

Granting table privileges

Use GRANT to add rights without changing ownership. Example: give reporting_role read-only access to Orders and OrderItems.

GRANT SELECT ON public.Orders, public.OrderItems TO reporting_role;

Granting sequence usage

If the table has a serial or identity column, also grant USAGE and SELECT on the sequence or inserts will fail.

How do I fix ownership problems?

“permission denied for table” often means the table is owned by a different user. Connect as the owner or a superuser and run ALTER TABLE … OWNER TO new_owner;.

How can I automate future grants?

Use ALTER DEFAULT PRIVILEGES so that new tables inherit the correct rights. This prevents forgotten grants during deployments.

What about functions and RLS?

Executing functions

Grant EXECUTE on CREATE FUNCTION objects. Without it, calling the function raises “permission denied”.

Row-level security

If RLS is ON, even superusers need a matching policy. Use ALTER TABLE … DISABLE ROW LEVEL SECURITY or define a permissive policy.

Best practices to avoid denied errors

Create dedicated roles for apps, follow least privilege, script your grants, and test migrations in staging. Review logs with log_statement = 'ddl' to spot missing privileges early.

Why How to Fix “Access Denied” Errors in PostgreSQL is important

How to Fix “Access Denied” Errors in PostgreSQL Example Usage


-- Allow the web app to create orders but keep read-only product access
GRANT SELECT ON public.Products TO web_app;
GRANT INSERT, SELECT ON public.Orders TO web_app;
GRANT INSERT, SELECT ON public.OrderItems TO web_app;
-- Ensure the OrderItems_id_seq sequence can be used during inserts
GRANT USAGE, SELECT ON SEQUENCE public.OrderItems_id_seq TO web_app;

How to Fix “Access Denied” Errors in PostgreSQL Syntax


-- Granting object privileges
GRANT { SELECT | INSERT | UPDATE | DELETE | ALL PRIVILEGES }
ON TABLE schema.table_name [, ...]
TO { role_name | PUBLIC } [ WITH GRANT OPTION ];

-- Granting sequence privileges (needed for serial/identity)
GRANT { USAGE | SELECT | UPDATE } ON SEQUENCE schema.seq_name TO role_name;

-- Changing object ownership
ALTER TABLE schema.table_name OWNER TO new_owner;

-- Setting default privileges for future objects
ALTER DEFAULT PRIVILEGES FOR ROLE role_name
IN SCHEMA schema_name
GRANT SELECT ON TABLES TO reporting_role;

-- Example (ecommerce)
GRANT SELECT, INSERT ON public.Orders TO order_service;
GRANT SELECT ON public.Products TO order_service;

Common Mistakes

Frequently Asked Questions (FAQs)

Do I need superuser rights to fix permission errors?

No. You only need to connect as the object owner or a role with GRANT OPTION on that object.

Why do I still get denied after granting SELECT?

Row-level security may block the row. Disable RLS or add a policy that matches the session role.

How can I see who owns a table?

Query pg_class.relowner joined with pg_roles.rolname or run \dt+ schema.table in psql.

Want to learn about other SQL terms?

Trusted by top engineers on high-velocity teams
Aryeo Logo
Assort Health
Curri
Rubie Logo
Bauhealth Logo
Truvideo Logo
Welcome to the Galaxy, Guardian!
Oops! Something went wrong while submitting the form.