You granted a user SELECT on the table. They still can’t query it, and instead get:
Error in SQL statement: SecurityException:
User does not have USAGE on Database 'sales'
-- Unity Catalog phrases it as:
PERMISSION_DENIED: User does not have USE SCHEMA on Schema 'main.sales'This one confuses almost everyone, because it feels like a bug: you did grant access to the table. The catch is that in Databricks, table permissions are a hierarchy — and SELECT on a table means nothing if the user can’t first “enter” the database that contains it.
⚡ Quick fix
Grant the missing “entry” privilege on the database (schema), then the table privilege:
-- Legacy Hive metastore (Table ACLs)
GRANT USAGE ON DATABASE sales TO `data_analysts`;
GRANT SELECT ON TABLE sales.orders TO `data_analysts`;
-- Unity Catalog (use USE CATALOG + USE SCHEMA instead of USAGE)
GRANT USE CATALOG ON CATALOG main TO `data_analysts`;
GRANT USE SCHEMA ON SCHEMA main.sales TO `data_analysts`;
GRANT SELECT ON TABLE main.sales.orders TO `data_analysts`;Grant to a group (like data_analysts), not to individual users — it’s the difference between managing access once and managing it forever.
What the error actually means
Databricks permissions cascade down a tree: catalog → schema (database) → table. To read a table, a user needs a privilege at every level of the path, not just on the table itself:
USE CATALOGon the catalog — permission to “see into” the catalogUSE SCHEMA(calledUSAGEin the legacy Hive metastore) on the schema/database — permission to “see into” the databaseSELECTon the table — permission to read the actual data
USAGE / USE SCHEMA doesn’t let anyone read data on its own. It’s a doorway privilege: it lets the user reach objects inside the database. Without it, SELECT on the table is a key to a room they can’t walk up to.
Reading a table needs a privilege at every level of the path — not just on the table.
Why it happens
- You granted SELECT but forgot the doorway. The most common cause by far — table access without the schema/catalog
USEprivilege above it. - A new schema or catalog. Freshly created objects only grant access to their owner. Everyone else needs explicit
USEprivileges before they can reach anything inside. - The user is new to a group that never had USAGE. The group had table grants but was never given the doorway privilege, so nobody in it could actually get in.
- Table Access Control is enabled on the cluster/warehouse, which is what enforces these checks in the first place.
How to fix it, step by step
Step 1: See what the user currently has
-- Unity Catalog
SHOW GRANTS `someone@company.com` ON SCHEMA main.sales;
-- Legacy Hive metastore
SHOW GRANTS `someone@company.com` ON DATABASE sales;If USE SCHEMA / USAGE is missing from the list, you’ve found the gap.
Step 2: Grant the whole path, top to bottom
-- Unity Catalog: grant at each level down to the object
GRANT USE CATALOG ON CATALOG main TO `data_analysts`;
GRANT USE SCHEMA ON SCHEMA main.sales TO `data_analysts`;
GRANT SELECT ON TABLE main.sales.orders TO `data_analysts`;You must grant USE SCHEMA on every schema in the path you want reachable. If the data spans several schemas, each one needs its own doorway grant.
Step 3: Prefer a broad “reader” pattern
Instead of granting SELECT table by table, many teams give a reader group USE CATALOG + USE SCHEMA once, then grant SELECT on the schema so all its current and future tables are readable:
GRANT USE CATALOG ON CATALOG main TO `data_analysts`;
GRANT USE SCHEMA ON SCHEMA main.sales TO `data_analysts`;
GRANT SELECT ON SCHEMA main.sales TO `data_analysts`; -- all tables in the schemaNew tables added to main.sales later are automatically readable — no repeat grants, no repeat tickets.
How to verify it’s fixed
SHOW GRANTSnow listsUSE SCHEMA(orUSAGE) andSELECTfor the group.- The user runs a
SELECTagainst the table and it returns rows — noSecurityException/PERMISSION_DENIED. - Have them re-run in a fresh query; grants apply to new statements immediately.
How to prevent it
- Grant to groups, never individuals. People change teams; groups don’t. This is the single biggest time-saver in access management.
- Think in paths, not tables. Whenever you grant a table, ask “can they reach it?” — the
USEprivileges above it must exist too. - Use schema-level SELECT for reader groups so new tables inherit access automatically.
- Standardize a reader/writer/admin group model per catalog, granted once, so this error stops recurring across the org.
When it’s actually something else
- Path-based access: if you’re reading files by path (not a table), you may instead hit “does not have permission SELECT on ANY File” — a different privilege about direct file access.
- Object ownership: some operations (like
ALTERorDROP) need ownership, not justUSE+SELECT. - Wrong metastore: granting in Unity Catalog while querying a legacy Hive metastore table (or vice versa) won’t take effect — confirm which one the table actually lives in.
For the official reference, see the Databricks knowledge base; the grant patterns above come from setting up access control on real workspaces.
Frequently Asked Questions
What does “User does not have USAGE on database” mean in Databricks?
It means the user lacks the USAGE privilege (called USE SCHEMA in Unity Catalog) on the database that contains the table. Databricks permissions are hierarchical, so a user needs USE on the catalog and schema to reach a table, in addition to SELECT on the table itself.
Why isn’t granting SELECT enough?
SELECT grants permission to read a table’s data, but not permission to reach the table. The user also needs USE SCHEMA (USAGE) on the schema and USE CATALOG on the catalog above it. Without those doorway privileges, SELECT alone still results in a permission error.
What is the difference between USAGE and USE SCHEMA?
They are the same concept in different systems. USAGE is the term in the legacy Hive metastore Table ACL model; USE SCHEMA (plus USE CATALOG) is the equivalent in Unity Catalog. Both grant the ability to access objects inside a database or schema without granting data access by themselves.
How do I grant USAGE on a database in Databricks?
In the legacy metastore, run GRANT USAGE ON DATABASE db_name TO `group`. In Unity Catalog, run GRANT USE CATALOG ON CATALOG catalog_name and GRANT USE SCHEMA ON SCHEMA catalog.schema TO `group`, then grant SELECT on the tables or schema.
Should I grant permissions to users or groups?
Grant to groups. Groups let you manage access once and add or remove people without re-granting privileges. Granting to individuals leads to inconsistent, hard-to-audit permissions and is a common source of recurring access errors.





