Databricks Error:
PERMISSION_DENIED
What does this error mean?
Databricks raises PERMISSION_DENIED when the principal running a query — a user account, service principal, or group — lacks the required privilege on a Unity Catalog or Hive Metastore securable. The error fires at query parse time, before any data is read, so the query fails immediately with no partial results. In pipeline context this typically surfaces during a scheduled Databricks Job, a notebook task, or a SQL warehouse query triggered by an orchestrator like Azure Data Factory or dbt Cloud. The symptom is a hard failure: the task status flips to FAILED, downstream Delta tables are not updated, and any Power BI dataset refresh that depends on those tables will also fail within its next refresh cycle. The error message includes the missing privilege and the securable path (e.g. `User does not have SELECT on table main.finance.revenue`).
Common causes
- 1User or service principal missing SELECT, MODIFY, or CREATE TABLE on a Unity Catalog securable. This is the most common cause after a Unity Catalog migration when old Hive grants are not carried over.
- 2The service principal running a scheduled job was not granted USE CATALOG and USE SCHEMA on the parent catalog and schema. Unity Catalog enforces hierarchical permissions — table-level grants alone are not enough.
- 3Row-level security (RLS) policies or column masks block the querying principal. The error message may not mention RLS explicitly, making this hard to diagnose without checking `DESCRIBE TABLE EXTENDED`.
- 4A workspace-local Hive Metastore table is queried through a Unity Catalog-enabled SQL warehouse, but the table was never registered in Unity Catalog. The warehouse cannot resolve the table and returns PERMISSION_DENIED instead of TABLE_NOT_FOUND.
- 5An external location or storage credential (e.g. for S3 or ADLS) is not granted to the principal. This happens when reading from external tables or using COPY INTO from a cloud storage path.
- 6Service principal credentials were rotated or the client secret expired, causing the authentication to fall back to an anonymous identity that has no grants.
- 7A cluster policy restricts data access configuration to specific service principals, and the job's cluster was started with a different identity than expected.
How to fix it
- 1Identify the exact missing privilege from the error message. It will say something like `User X does not have SELECT on table catalog.schema.table`. Note the principal, privilege, and securable.
- 2Run `SHOW GRANTS ON TABLE <catalog>.<schema>.<table>` in a Databricks SQL editor or notebook to see all current grants on the target object. Compare against the principal in the error.
- 3Grant the missing privilege: `GRANT SELECT ON TABLE <catalog>.<schema>.<table> TO <principal>`. For service principals, use the application ID: `GRANT SELECT ON TABLE main.finance.revenue TO `sp-etl-prod``.
- 4Verify hierarchical access: `SHOW GRANTS ON CATALOG <catalog>` and `SHOW GRANTS ON SCHEMA <catalog>.<schema>`. The principal needs USE CATALOG and USE SCHEMA on the parent objects. Grant if missing: `GRANT USE CATALOG ON CATALOG main TO `sp-etl-prod``.
- 5If the job runs on a SQL warehouse, open Databricks workspace → SQL Warehouses → select the warehouse → Data Access Configuration. Confirm the service principal or run-as identity listed there matches the one you just granted privileges to.
- 6Check for RLS or column masks: run `DESCRIBE TABLE EXTENDED <catalog>.<schema>.<table>` and look for row filter or column mask entries. If present, verify the querying principal is allowed by the filter function.
- 7After granting, re-run the failed job or query. Unity Catalog grants take effect immediately — no cluster restart needed. Verify the job completes successfully and downstream tables are refreshed.
Example log output
[2026-05-11T08:14:22.531Z] [ERROR] SparkDriverError: io.databricks.sql.SparkException: [PERMISSION_DENIED] User `sp-etl-prod@myorg.databricks.com` does not have SELECT on TABLE `main.finance.revenue`. SQLSTATE: 42000
[2026-05-11T08:14:22.534Z] [ERROR] Task run_id=489201 failed with status FAILED. Error code: PERMISSION_DENIED
[2026-05-11T08:14:22.540Z] [WARN] Job 12847 run 489201: no retry attempted (non-retryable error class)