The "Permission denied for schema" error occurs when a user tries to access objects within a schema without having the necessary USAGE privilege on that schema. Schemas are namespaces that contain database objects, and PostgreSQL requires explicit schema-level permissions before allowing access to objects within them.
Impact
This error prevents users from accessing any objects (tables, views, functions) within the schema, even if they have permissions on individual objects. It effectively blocks entire sections of the database from user access, causing widespread application failures.
Common Causes
- Missing USAGE privilege on the schema
- Schema permissions not granted after schema creation
- Default privileges not configured for new schemas
- Using custom schemas without proper permission setup
- Revoked schema access
- User attempting to access private schemas
- Search path not including the schema
Troubleshooting and Resolution Steps
Check schema permissions:
-- List all schemas and their privileges \dn+ -- Check specific schema permissions SELECT nspname, nspacl FROM pg_namespace WHERE nspname = 'your_schema';Grant USAGE privilege on schema:
-- Grant schema usage to user GRANT USAGE ON SCHEMA your_schema TO username; -- Grant to multiple users GRANT USAGE ON SCHEMA your_schema TO user1, user2, user3; -- Grant to all users (use with caution) GRANT USAGE ON SCHEMA your_schema TO PUBLIC;Grant comprehensive schema access:
-- Grant schema usage and object access GRANT USAGE ON SCHEMA your_schema TO username; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA your_schema TO username; GRANT USAGE ON ALL SEQUENCES IN SCHEMA your_schema TO username; GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA your_schema TO username;Configure default privileges for future objects:
-- Set default privileges for tables ALTER DEFAULT PRIVILEGES IN SCHEMA your_schema GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO username; -- For sequences ALTER DEFAULT PRIVILEGES IN SCHEMA your_schema GRANT USAGE ON SEQUENCES TO username; -- For functions ALTER DEFAULT PRIVILEGES IN SCHEMA your_schema GRANT EXECUTE ON FUNCTIONS TO username;Set up search_path to include the schema:
-- Set for current session SET search_path TO your_schema, public; -- Set for specific user permanently ALTER USER username SET search_path TO your_schema, public; -- Set database-wide default ALTER DATABASE mydb SET search_path TO your_schema, public;Grant CREATE privilege if user needs to create objects:
-- Allow creating new objects in schema GRANT CREATE ON SCHEMA your_schema TO username;Transfer schema ownership if needed:
-- Change schema owner ALTER SCHEMA your_schema OWNER TO new_owner;Create a role for schema access management:
-- Create role for schema access CREATE ROLE schema_users; -- Grant permissions to role GRANT USAGE ON SCHEMA your_schema TO schema_users; GRANT SELECT ON ALL TABLES IN SCHEMA your_schema TO schema_users; -- Add users to role GRANT schema_users TO user1, user2, user3;Check effective permissions:
-- Check if user has schema usage SELECT has_schema_privilege('username', 'your_schema', 'USAGE'); SELECT has_schema_privilege('username', 'your_schema', 'CREATE');For application setup, grant all necessary schema permissions:
-- Complete application user setup CREATE ROLE app_user WITH LOGIN PASSWORD 'secure_password'; GRANT CONNECT ON DATABASE mydb TO app_user; GRANT USAGE ON SCHEMA public TO app_user; GRANT USAGE ON SCHEMA app_schema TO app_user; GRANT ALL ON ALL TABLES IN SCHEMA app_schema TO app_user; GRANT ALL ON ALL SEQUENCES IN SCHEMA app_schema TO app_user; GRANT ALL ON ALL FUNCTIONS IN SCHEMA app_schema TO app_user; -- Future objects ALTER DEFAULT PRIVILEGES IN SCHEMA app_schema GRANT ALL ON TABLES TO app_user; ALTER DEFAULT PRIVILEGES IN SCHEMA app_schema GRANT ALL ON SEQUENCES TO app_user;
Additional Information
- The
publicschema has USAGE granted to PUBLIC by default - Custom schemas require explicit USAGE grants
- USAGE permission on schema is prerequisite for accessing any objects within
- Schema ownership doesn't automatically grant access to contained objects
- Regular audit of schema permissions is important for security
- Use schemas to organize related objects and implement access control boundaries
Frequently Asked Questions
Q: What's the difference between USAGE and CREATE privileges on a schema?
A: USAGE allows accessing existing objects in the schema, while CREATE allows creating new objects in the schema.
Q: Why can't I access a table even though I have SELECT permission on it?
A: You need both USAGE permission on the schema and SELECT permission on the table. Missing schema USAGE will cause "permission denied for schema" error.
Q: How do I grant access to all schemas?
A: You must grant individually for each schema:
DO $$
DECLARE
schema_name text;
BEGIN
FOR schema_name IN SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema'
LOOP
EXECUTE format('GRANT USAGE ON SCHEMA %I TO username', schema_name);
END LOOP;
END $$;
Q: What is search_path and how does it relate to schemas?
A: search_path defines the order in which PostgreSQL searches schemas for objects. Setting it helps users access objects without schema-qualifying names (e.g., table instead of schema.table).
Q: Can I revoke schema access from a user?
A: Yes, use REVOKE USAGE ON SCHEMA your_schema FROM username; Note that this only affects direct grants, not those inherited from roles.
Q: How do I see all permissions for a schema?
A: Use \dn+ schema_name in psql or query:
SELECT nspname, nspacl
FROM pg_namespace
WHERE nspname = 'your_schema';