a week ago
Hi everyone,
I am running into a permission issue when trying to query data from an external S3 storage location managed through Unity Catalog.
Here are the symptoms:
Any guidance from the community would be greatly appreciated!
a week ago
We hit something similar. In our case the job ran as a service principal that was missing the required UC privilege, even though the IAM role was fine. For path-based access thatโs READ FILES on the external location, for tables itโs SELECT, USE CATALOG/USE SCHEMA and for volumes itโs READ VOLUME. Granting the right one fixed it.
Few common causes and triage steps:
SHOW GRANTS ON EXTERNAL LOCATION my_location;
DESCRIBE EXTERNAL LOCATION my_location;โif privilege is missing, then
GRANT READ FILES ON EXTERNAL LOCATION my_location TO `user_or_sp`โDESCRIBE STORAGE CREDENTIAL my_credential;
LIST 's3://my-bucket/path/';โdatabricks external-locations get my_location
databricks workspace-bindings get-bindings external-location my_locationโ
a week ago
A correct IAM role is necessary but not sufficient. Access to an external location goes through two separate checks, and the wording of the error tells you which one failed. Here's how to find it quickly.
Step 0 โ Capture the exact error. Run a direct path read from the same compute and identity that fails:
LIST 's3://<bucket>/<prefix>/';
Then match the message:
Error text containsFailing layerGo to
PERMISSION_DENIED: User does not have READ FILES on External Location ... (or USE CATALOG / USE SCHEMA / SELECT) | Unity Catalog privileges | Step 1 |
"not accessible in the current workspace" / location greyed out in Catalog Explorer | Workspace binding | Step 2 |
"AWS IAM role does not have READ permissions on url ...", "403 Forbidden from cloud storage provider", "Failed on assuming role" | AWS (trust, S3, KMS, bucket policy) | Step 4 |
Errors about the Unity API token, or access mode | Compute | Step 3 |
Step 1 โ Unity Catalog privileges (the most common cause). A storage credential does not grant users anything. The calling principal needs privileges on the external location, and for tables, on the catalog, schema and table too. For a job, that means the job's run-as identity.
SHOW GRANTS ON EXTERNAL LOCATION `my_location`;
GRANT READ FILES ON EXTERNAL LOCATION `my_location` TO `data_engineers`;
GRANT WRITE FILES ON EXTERNAL LOCATION `my_location` TO `data_engineers`; -- writes need READ FILES too
-- for external tables / volumes on that path:
GRANT USE CATALOG ON CATALOG my_cat TO `data_engineers`;
GRANT USE SCHEMA ON SCHEMA my_cat.my_sch TO `data_engineers`;
GRANT SELECT ON TABLE my_cat.my_sch.my_tbl TO `data_engineers`; -- or READ VOLUME on a volume
Notes:
Step 2 โ Workspace bindings. If the location (or its catalog) is set to isolated, it only works from bound workspaces.
databricks external-locations get my_location # check isolation_mode
databricks workspace-bindings get-bindings external-location my_location
Either add your workspace ID, or tick "All workspaces have access" on the location's Workspaces tab.
Step 3 โ Compute. Use a UC-capable access mode:
Step 4 โ AWS side. Start with Catalog > External data > Credentials > your credential > Validate configuration, then Test connection on the external location. The results show which step fails: self-assume, read, list, write or delete. Then check, in this order:
Logs to check:
SELECT event_time, user_identity.email, action_name, request_params, response.status_code, response.error_message
FROM system.access.audit
WHERE service_name = 'unityCatalog'
AND event_date >= current_date() - 1
AND response.status_code <> 200
ORDER BY event_time DESC;
If Validate configuration passes, the bucket policy has no Deny, and you still get a 403, open a support ticket with the request ID from the error. That case needs a server-side look at the assume-role attempt.
Tuesday
Hi @Khasim_1
Are you doing direct file access or via unity catalog tables/volumes? if you are reading directly then you need to grant READ FILES to the identity used by your pipeline/notebook to this external location.
If you are accessing via uc table/volumes then you dont need this READ FILES.. then you have to make sure proper permissions are granted to catalog/schema/table for the same identity either user or sp running this notebook/job. (e.g. USE CATALOG, USE SCHEMA, SELECT or READ on table/volume
this should solve your issue , if not let me know. Thanks
Friday
Hello @Khasim_1, I took a look at both internal and external documentation and here is what I found.
First, credit to @data_pulse, @pradeep_singh and @saurabh18cs, who've already laid out the standard triage. Capture the exact error. Confirm the job's run-as identity (user or service principal) has the right UC grants: READ FILES on the external location for direct path reads, or USE CATALOG, USE SCHEMA and SELECT (or READ VOLUME) for tables and volumes. Check the workspace binding if the location is isolated, and make sure the compute is UC-capable (Standard, Dedicated, SQL warehouse or serverless). Pradeep's error-text-to-layer table is the fastest way to find out which of those you're hitting.
I'll add the pieces that may add challengs right after a metastore gets attached.
The role on your cluster probably isn't the one being checked. Before UC, S3 access usually rode on the cluster's instance profile. Once an external location covers a path, UC enforces access to that path on UC-enabled compute and ignores cluster-level credentials and Spark configs. The role that matters is the one inside the storage credential, and the Databricks control plane assumes it, not your cluster. So the cluster role can look perfect in AWS and tell you nothing.
On that credential role, check three things:
0000), then has you copy the external ID from the "credential created" dialog and go back to update the trust policy. Skip that last step and the credential still shows as created, but every assume-role call fails.Grants don't transfer either. Attaching a metastore carries nothing over from instance profiles or legacy table ACLs, and UC grants only go to account-level users, groups and service principals. If your workspace predates UC and the grant went to a workspace-local group, it won't apply. SHOW GRANTS ON EXTERNAL LOCATION my_location shows who actually has what; compare it with the identity on the failed run.
Logs settle which side is at fault quickly. Query system.access.audit with service_name = 'unityCatalog' for the denied request, and check CloudTrail for the role. No AssumeRole call at all means UC blocked it before reaching AWS; an AssumeRole or S3/KMS AccessDenied means the problem is in AWS.
If you're mid-migration and need existing jobs running while you sort out grants, the external location owner can turn on fallback mode. UC checks the caller's grants first and, if those fail, falls back to the cluster's instance profile or Spark config credentials. Treat it as a temporary bridge and switch it off once the grants are in place.
References:
Regards, Louis.
4 hours ago
This type of issue can sometimes occur when AWS IAM permissions are correctly configured, but Unity Catalog is unable to authorize access through the storage credential or external location. I would recommend checking a few things before changing the IAM role.
Here are some troubleshooting steps worth exploring:
Verify Storage Credential Permissions: Make sure the storage credential is accessible to the user or service principal executing the query. Check whether the required READ FILES privilege has been granted.
Check External Location Grants: Verify that the user has the necessary permissions on the external location. For example, READ FILES is required to read or list files, while WRITE FILES is needed for write operations.
Validate IAM Trust Relationship: Check the AWS IAM role's trust policy and confirm that it allows the correct Databricks IAM principal to assume the role. Also verify the external ID if one is required.
Review S3 Bucket Policies: Even when the IAM role has the correct permissions, an S3 bucket policy, explicit deny statement, or restrictive VPC endpoint policy can block access. Check permissions for s3:ListBucket and s3:GetObject on the relevant bucket and objects.
Inspect CloudTrail Logs: AWS CloudTrail can help identify whether the request is being denied by AWS. Look for AccessDenied events and check which principal is making the request.
Check Unity Catalog Configuration: Confirm that the external location points to the correct S3 path and uses the intended storage credential. Also check for overlapping external locations or conflicting storage paths.
Test with a Simple SQL Command: Try listing files using:
LIST 's3://your-bucket/your-path/';
This can help narrow down whether the issue is related to basic storage access or a higher-level table permission.
One important point: AWS IAM authorization and Unity Catalog authorization are two separate permission layers. Both must allow the requested operation.
I would start by checking the Unity Catalog grants and AWS CloudTrail logs. These two checks can often help identify where the authorization failure is happening. ๐ฉ
Hope this helps someone facing a similar issue! ๐๐ผ