Azure Error Guide: 'AuthorizationPermissionMismatch' — Fix Blob Data-Plane RBAC
Fix Azure Storage 'AuthorizationPermissionMismatch' (403): grant a data-plane role like Storage Blob Data Contributor, not control-plane Contributor, and verify with az role assignment on the right scope.
- #azure
- #cloud
- #troubleshooting
- #errors
Stuck on this Azure with AI error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
AuthorizationPermissionMismatch is an HTTP 403 returned by Azure Storage when you authenticate to the data plane (blob, queue, table, or file) with a Microsoft Entra identity that is valid but lacks a data role for the operation. The identity signed in successfully — this is not an authentication failure — but the RBAC roles it holds do not grant the specific blob/queue/table action requested.
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>AuthorizationPermissionMismatch</Code>
<Message>This request is not authorized to perform this operation using this permission.
RequestId:00000000-0000-0000-0000-000000000000
Time:2026-07-08T12:00:00.0000000Z</Message>
</Error>
The Azure CLI surface of the same error:
ErrorCode:AuthorizationPermissionMismatch
This request is not authorized to perform this operation using this permission.
The critical insight: control-plane roles like Owner and Contributor do not grant blob data access. You can manage the storage account and still be denied when reading a blob.
Symptoms
az storage blob upload/download/list(or an SDK/app usingDefaultAzureCredential) returns 403AuthorizationPermissionMismatch, whileaz storage account showworks fine.- Portal shows “You do not have permission to view or download” on containers even though you can see the account and change its settings.
- An AKS pod or App Service using a managed identity gets 403 on blob calls despite the identity being assigned to the resource.
- The failure started after switching a client from account-key/SAS auth to Entra ID (
--auth-mode login) authentication. - Some operations work and others don’t (e.g. list containers works via control plane, but reading a blob fails).
Common Root Causes
- Control-plane role instead of data role. The identity has Owner/Contributor (which grant
Microsoft.Storage/storageAccounts/*management actions) but notStorage Blob Data Reader/Contributor(which grant.../blobServices/containers/blobs/read|write). - Wrong data role for the action.
Storage Blob Data Readerwas granted but the code writes; write needsStorage Blob Data Contributor. - Assignment at the wrong scope. The data role was granted on a different resource group, subscription, or a different storage account than the one being accessed.
- Role assignment not propagated. Data-plane role changes can take several minutes (occasionally longer) to take effect.
- Wrong identity in a multi-identity setup. A VM/AKS with several user-assigned identities picked a different one than the one that holds the role;
DefaultAzureCredentialselected an unexpected credential. - Queue/table/file equivalents. The same pattern applies with
Storage Queue Data Contributor,Storage Table Data Contributor, and SMB/file data roles — a blob role does not cover queues or tables.
Diagnostic Workflow
Confirm which identity is actually making the call:
az account show --query user -o json
# For a managed identity on a VM/AKS, get its object (principal) id:
az identity show --name <uami> --resource-group <rg> --query principalId -o tsv
List the role assignments that identity has on the target storage account — look for a Data role, not just Contributor:
az role assignment list \
--assignee <objectId-or-principalId> \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account> \
--query "[].roleDefinitionName" -o tsv
If that returns only Contributor / Owner and no Storage Blob Data *, you have found the cause.
Reproduce the data-plane call explicitly with Entra auth (not the account key) to isolate it from key-based access:
az storage blob list \
--account-name <account> \
--container-name <container> \
--auth-mode login \
-o table
Check whether key-based access still works, which confirms the account is healthy and the problem is purely RBAC on the data plane:
az storage blob list --account-name <account> --container-name <container> \
--auth-mode key --account-key <key> -o table
Example Root Cause Analysis
An App Service uses a system-assigned managed identity to read configuration blobs. During setup the platform team granted the identity Contributor on the storage account “so it can do everything.” In production the app gets:
AuthorizationPermissionMismatch (403) on GET /config/appsettings.json
Listing the identity’s roles on the account shows only Contributor. Contributor grants management operations (Microsoft.Storage/storageAccounts/*) but explicitly does not include the blob data actions Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read. The data plane check therefore fails with a mismatch.
The fix is to grant the correct data role at the account (or narrower, the container) scope:
az role assignment create \
--assignee <appservice-principalId> \
--role "Storage Blob Data Reader" \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account>
Because the app only reads, Storage Blob Data Reader is the least-privileged fit; use Storage Blob Data Contributor only if it also writes. After a few minutes for propagation, the read succeeds.
Prevention Best Practices
- Assign data roles for data access. For blob/queue/table access via Entra ID, always grant
Storage Blob Data Reader/Contributor(or the queue/table equivalents). Never rely on Owner/Contributor for data-plane operations. - Match the role to the operation. Read-only workloads get
...Data Reader; only grant...Data Contributorwhere writes happen. This keeps least privilege and avoids over-broad grants. - Scope narrowly. Assign at the container or account level the workload actually uses, not at subscription scope.
- Pin the managed identity. With
DefaultAzureCredentialand multiple user-assigned identities, set the client id explicitly so the app uses the identity that holds the role. - Account for propagation. After granting a data role, allow several minutes before expecting success; build a retry into first-run automation.
- Prefer Entra auth over keys. Moving off account keys/SAS to Entra RBAC is the right direction — just remember it requires data roles, which key-based access bypassed.
Quick Command Reference
# Which identity is calling
az account show --query user -o json
az identity show -n <uami> -g <rg> --query principalId -o tsv
# Does it hold a DATA role on THIS account?
az role assignment list --assignee <objectId> \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account> \
--query "[].roleDefinitionName" -o tsv
# Reproduce with Entra auth
az storage blob list --account-name <account> --container-name <container> --auth-mode login -o table
# Grant least-privilege data role
az role assignment create --assignee <objectId> \
--role "Storage Blob Data Reader" \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account>
Conclusion
AuthorizationPermissionMismatch is Azure Storage drawing a hard line between the control plane and the data plane. A valid Entra identity with Owner or Contributor can manage the storage account all day and still be denied when it reads a blob, because blob/queue/table access requires a dedicated data role. Confirm which identity is calling, check its assignments on the exact account scope for a Storage Blob Data * role, grant the least-privileged one that matches the operation, and wait for propagation. Bake data-role assignment into your identity onboarding and this 403 disappears from your migration to key-less, Entra-based storage access.
Fixed it? Get 500 Azure with AI & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.