---
cuppy_hub: azure
cuppy_path: reference/storage/access-errors.md
cuppy_section: docs
cuppy_doc: N89G-N7P4
cuppy_doc_uuid: 3496b370-5269-4a7b-bf7f-cf819c384d34
cuppy_permalink: https://cuppy.io/azure/d/N89G-N7P4
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/azure/docs/reference/storage/access-errors
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 29bf7be9ed015be1c2c76c386f45e3271dcdd065c1750e1e07521acabc465cd8
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Storage access errors — 401, 403 and 409

**A storage data request passes four gates in order: TLS and protocol, the network (firewall, public network access, perimeter), authentication (Entra token, Shared Key or SAS), then authorization (data role, ACL or SAS permissions).** The error code says which gate refused. Read it from `x-ms-error-code` (header) or `<Code>` (XML body); in TypeScript it is `e.details?.errorCode` (`guides/storage/access-blobs-from-typescript.md`).

These are **data-plane** errors. Control-plane errors on the storage account resource itself (`AuthorizationFailed`, `ScopeLocked`) are in `reference/arm/errors.md`.

## Entra ID (OAuth) requests

| Code / message | Cause → fix | Check |
|---|---|---|
| 403 `AuthorizationPermissionMismatch` `This request is not authorized to perform this operation using this permission.` | The caller has a valid token but **no data role**. Owner, Contributor and Storage Account Contributor manage the account and give no data access. Assign **Storage Blob Data Reader / Contributor / Owner** (or the Queue, Table or File equivalents) at the account or container | `az role assignment list --assignee <object-id> --scope <account-id> --include-inherited -o table` |
| Same, right after assigning the role | Propagation. Microsoft's page gives both "up to 10 minutes" and "up to 30 minutes"; at management-group scope data actions can take up to 12 hours. Also check for a deny assignment | Retry after 10–30 minutes; `az role assignment list --scope <account-id>` |
| Same, for an overwrite or a delete | The role or SAS covers write but not delete; overwriting a blob needs both | Compare the operation with the role's `dataActions` |
| 401 `NoAuthenticationInformation` / `InvalidAuthenticationInfo` `Server failed to authenticate the request. Please refer to the information in the www-authenticate header.` | No `Authorization` header, or a token for the wrong audience. The scope is `https://storage.azure.com/.default`. Also returned to anonymous requests (service version 2019-12-12+) when anonymous access is off | Decode the token: `aud` must be `https://storage.azure.com` |
| 400 `InvalidAuthenticationInfo` `The authentication information wasn't provided in the correct format. Verify the value of Authorization header.` | Malformed header (hand-built `Bearer` value, missing `x-ms-version`) | Use an `@azure/storage-*` client instead of raw HTTP |
| 403 `AuthorizationPermissionMismatch` on a hierarchical-namespace account, role present | ACLs only grant; but with **no** role, the caller also needs **Execute** on every parent folder | `reference/storage/adls-gen2.md` |

## Shared Key and SAS requests

`KeyBasedAuthenticationNotPermitted`, `AuthenticationFailed` (SAS expiry, signature, format), and the SAS `Authorization…Mismatch` codes: `reference/storage/sas-and-key-errors.md`.

## Network, account and transport

| Code / message | Cause → fix | Check |
|---|---|---|
| 403 `AuthorizationFailure` `This request is not authorized to perform this operation.` | The **firewall** or **public network access** refused the caller: `defaultAction: Deny` with no matching IP, VNet or resource-instance rule; `publicNetworkAccess: Disabled` without a private endpoint; or a network security perimeter. Same-region Azure callers use private IPs, so **IP rules can't admit them**: use a VNet rule (service endpoint) or a private endpoint | `az storage account show -n <acct> --query "{public:publicNetworkAccess, acls:networkRuleSet}"`; `reference/storage/network-and-firewall.md` |
| `AuthorizationFailure` from the portal's data browser, while listing containers works | Listing can go through the control plane; reading blobs is data plane and hits the firewall | Same |
| 409 `PublicAccessNotPermitted` `Public access is not permitted on this storage account.` | Creating or updating a container with a public access level (even an **empty** `x-ms-blob-public-access` header) when `allowBlobPublicAccess` is false. Omit the header, or allow public access at the account first | `az storage account show -n <acct> --query allowBlobPublicAccess` |
| 401 (service 2019-12-12+), 409 or 404 (older versions) on an **anonymous** read | Anonymous access off at the account or container. Prefer authenticating; anonymous access needs the account setting, the container level and a read request | `reference/storage/access-models.md` |
| 400 naming the TLS version | Client uses TLS 1.0/1.1. Blob Storage ended TLS 1.0/1.1 on February 3, 2026, for the whole account (Files, Queue, Table too). Upgrade the client to TLS 1.2+ | Client runtime and OS TLS settings |
| 403 `The copy operation is not within the allowed copy scope` (field wording varies) | `allowedCopyScope` is `AAD` or `PrivateLink` and the source is outside it | `az storage account show -n <acct> --query allowedCopyScope` |
| 403 `InsufficientAccountPermissions` `Read operations are currently disabled.` / `Write operations aren't allowed.` | The account currently refuses reads or writes; the message says which. Microsoft's code table gives no cause | `az storage account show -n <acct> --query "{status:statusOfPrimary, failover:failoverInProgress}"`; Resource Health |
| 403 `AccountIsDisabled` `The specified account is disabled.` | The subscription or account is disabled | `az account show --query state` |
| 403 `KeyVaultAccessTokenCannotBeAcquired` / `KeyVaultEncryptionKeyNotFound` / `KeyVaultVaultNotFound` | Customer-managed keys: the account's identity can't reach the vault or key (role, network, deleted key) | `az storage account show -n <acct> --query encryption`; `reference/keyvault/access-and-errors.md` |

## When none of these fits

Walk the gates in order with one call: `az storage account show -n <acct> --query "{tls:minimumTlsVersion, public:publicNetworkAccess, acls:networkRuleSet.defaultAction, sharedKey:allowSharedKeyAccess, oauthDefault:defaultToOAuthAuthentication, anon:allowBlobPublicAccess, hns:isHnsEnabled}"`. Then confirm which identity actually called (`reference/azure-identity/credential-chain.md`) and its data roles (`guides/identity/fix-access-denied.md`). Data errors past these gates (404, 409, 412, 503): `reference/storage/data-errors.md`.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 107 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/azure/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
