---
cuppy_hub: azure
cuppy_path: reference/storage/data-errors.md
cuppy_section: docs
cuppy_doc: TYA1-XKAP
cuppy_doc_uuid: a66ae7f8-c6b6-4968-9bcc-a54ee55a1e12
cuppy_permalink: https://cuppy.io/azure/d/TYA1-XKAP
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/azure/docs/reference/storage/data-errors
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: d49c6407d8a876b79d3f558404fcf4feed23783ebcf746daeb50aede864de06e
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Storage data errors — 404, 409, 412, 416, 503

These come back once the request is authorized (`reference/storage/access-errors.md` covers 401 and 403). Messages are the REST tables' wording; the service appends `RequestId:` and `Time:` lines. Status 409 errors are usually **state**, not bugs: read the code before retrying.

## Not found, exists, being deleted

| Code / message | Cause → fix | Check |
|---|---|---|
| 404 `ContainerNotFound` `The specified container does not exist.` | Wrong container name (lowercase, 3–63 characters), wrong account, or never created. Create it with `createIfNotExists()` | `az storage container exists -n <c> --account-name <acct> --auth-mode login` |
| 404 `BlobNotFound` `The specified blob does not exist.` | Name is case-sensitive and includes the virtual "folder" path; or the blob was deleted (soft delete may still hold it) | `az storage blob list -c <c> --prefix <path> --account-name <acct> --auth-mode login --include d` |
| 404 `ResourceNotFound` `The specified resource doesn't exist.` | Generic form, also from Queue and Table | Name and endpoint (`blob.` vs `dfs.` vs `queue.`) |
| 409 `ContainerAlreadyExists` / `BlobAlreadyExists` | Create without overwrite on an existing name. Use `createIfNotExists()`, or upload with overwrite | Expected on reruns: treat as success when idempotent |
| 409 `ContainerBeingDeleted` `The specified container is being deleted.` | A container of that name was just deleted; deletion takes time. Retry later or use a new name | Retry with backoff; don't delete and re-create in tests |
| 404 `FilesystemNotFound` / `PathNotFound` (Data Lake) | Same as the Blob codes on the `dfs` endpoint | `az storage fs exists`, `az storage fs file exists` |

## Leases and conditional requests

| Code / message | Cause → fix | Check |
|---|---|---|
| 412 `LeaseIdMissing` `There is currently a lease on the blob/container and no lease ID was specified in the request.` | Another writer (or a crashed one) holds a lease. Pass the lease ID, wait for it to expire, or break it deliberately | `az storage blob show … --query properties.lease` |
| 412 `LeaseIdMismatchWithBlobOperation` / 409 `LeaseAlreadyPresent` | Wrong lease ID, or acquiring a lease someone holds | Same |
| 412 `LeaseLost` `A lease ID was specified, but the lease for the blob/container has expired.` | Lease ran out (15–60 s unless infinite) during a long write: renew it | Lease duration vs the work's length |
| 412 `ConditionNotMet` `The condition specified in the conditional header(s) was not met for a write operation.` | Optimistic concurrency working as designed: the ETag (`If-Match`) changed because someone else wrote. Re-read, merge, retry | Compare the ETag you hold with `az storage blob show … --query properties.etag` |
| 304 `ConditionNotMet` on a read | `If-None-Match` matched: your cached copy is current | Not an error |

## Tiers, immutability and limits

| Code / message | Cause → fix | Check |
|---|---|---|
| 409 `BlobArchived` `This operation is not permitted on an archived blob.` | Archive is offline. Rehydrate to hot, cool or cold (copy or set tier); it can take up to 15 hours | `properties.blobTier`, `properties.archiveStatus` |
| 409 `BlobBeingRehydrated` | Rehydration in progress | `archiveStatus` |
| 409 `BlobImmutableDueToPolicy` / `BlobImmutableDueToLegalHold` | Time-based retention or a legal hold: the blob can't change or be deleted until it ends | `az storage container immutability-policy show` / `az storage container legal-hold show` |
| 409 `BlockCountExceedsLimit` | More than 50,000 committed or 100,000 uncommitted blocks. Use larger blocks (the SDK's `uploadFile`/`uploadStream` choose sizes) | Block size × count |
| 400 `InvalidBlockList` / `InvalidBlockId` | Block IDs not Base64, or of differing lengths within one blob | Let the SDK stage blocks |
| 416 `InvalidRange` `The range specified is invalid for the current size of the resource.` | Ranged read past the end | Blob `contentLength` |
| 413 `RequestBodyTooLarge` | A single Put exceeds the operation's maximum: use block upload | SDK upload helpers |
| 400 `Md5Mismatch` | Content changed in transit, or the MD5 was computed over different bytes | Recompute over the exact upload buffer |

## Hierarchical namespace (ADLS Gen2)

| Code / message | Cause → fix | Check |
|---|---|---|
| 409 `BlobOperationNotSupported` (Put Block / Put Block List on a file created by `Path - Create`) | Blob and Data Lake APIs can't both write one file. Overwrite with Put Blob, or write with the Data Lake client | `reference/storage/adls-gen2.md` |
| 409 `InvalidFlushOperation` `The resource was created or modified by the Blob Service API and cannot be written to by the Data Lake Storage Service API.` | The reverse case | Same |
| 409 `DirectoryNotEmpty` `The recursive query parameter value must be true to delete a non-empty directory.` | Delete with `recursive: true`. Blob API Delete only removes empty directories | — |
| 409 `PathConflict` / `PathAlreadyExists` | A file exists where a directory is expected, or the reverse | `az storage fs file show` |
| Page-blob, append-seal or incremental-copy calls fail | Not supported on hierarchical-namespace accounts | Use a separate account |

## Copy

| Code / message | Cause → fix | Check |
|---|---|---|
| 500 `CannotVerifyCopySource` `Could not verify the copy source within the specified time.` | The destination service couldn't read the source: source firewall, private endpoint in another VNet, or the source SAS/role doesn't allow read | Can the destination account reach and read the source URL? |
| 400 `CopyAcrossAccountsNotSupported` | The operation (for example some incremental copies) requires one account | Use Copy Blob from URL with a SAS or Entra source auth |
| 409 `PendingCopyOperation` / `NoPendingCopyOperation` | Starting a copy while one runs, or aborting none | `properties.copy.status` |

## Server busy and timeouts

| Code / message | Cause → fix | Check |
|---|---|---|
| 503 `ServerBusy` `Operations per second is over the account limit.` / `Ingress is over the account limit.` / `Egress is over the account limit.` / `The server is currently unable to receive requests. Please retry your request.` | Account scalability target reached. Retry with exponential backoff (the SDKs retry by default: 4 tries, 4 s base, 120 s cap); spread load over prefixes or accounts; request higher limits through Support. The limit values are adjustable and not typed here | Azure Monitor metric `Transactions` split by `ResponseType`; scalability targets page |
| 500 `OperationTimedOut` `The operation could not be completed within the permitted time. The operation may or may not have succeeded on the server side. Please query the server state before retrying the operation.` | Check state before retrying a non-idempotent write | Read the blob's properties first |
| 500 `InternalError` | Transient: retry with backoff | — |
| 400 `InvalidResourceName` / `OutOfRangeInput` | Names: containers lowercase letters, numbers and hyphens, 3–63; blob names up to 1,024 characters | Name rules on Learn's naming page |


---
<!-- 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 -->
