How to Troubleshoot Azure Storage Blobs

Microsoft Fix Intermediate 15 min read Official Docs Grounded Updated April 20, 2026

Why This Is Happening

I've seen this scenario play out more times than I can count: a developer deploys a perfectly functioning app to Azure, opens the browser, and instead of their beautifully stored blob data, they get a cryptic 403 AuthorizationPermissionMismatch or a soul-crushing 404 BlobNotFound. The Azure portal shows the storage account is running fine. The blobs are clearly there. And yet , nothing works. I know this is frustrating, especially when production is down and your team is watching.

Azure Blob Storage is one of the most powerful object storage services available, handling everything from backup archives to media streaming pipelines. But that power comes with a layered security and configuration model that trips up even seasoned Azure architects. When something goes wrong, the error messages are rarely clear about what exactly broke or where to look first.

Here's a breakdown of the most common culprits behind Azure Storage Blob troubleshooting headaches:

  • Authentication failures (401/403): Expired SAS tokens, wrong access keys, missing role assignments, or Shared Key authentication being disabled at the account level.
  • Network and firewall rules: A storage account firewall set to "Selected networks" with your client IP or virtual network not whitelisted , something that's caused more midnight incidents than I care to admit.
  • Throttling (HTTP 503 / RequestRateTooHigh): Hitting the ingress/egress or IOPS limits for your storage account's performance tier.
  • Blob lifecycle and tier issues: Trying to read a blob in the Archive access tier without rehydrating it first, Azure returns error code BlobArchived and most apps don't handle it gracefully.
  • Lease conflicts (HTTP 409 LeaseIdMissing or LeaseAlreadyPresent): An application crashed mid-write and left an active lease on a blob, blocking all subsequent write operations.
  • CORS misconfigurations: Browser-based clients getting blocked on preflight requests because the storage account's CORS rules don't include the right origin or allowed methods.
  • Soft delete and versioning surprises: A blob appears "deleted" but is still being billed, or a versioned blob has dozens of hidden versions eating into your storage quota.

The frustrating reality is that Azure's own error messages often only tell you that something failed, not why. A 403 can mean five completely different things depending on your auth model. This guide walks you through every layer, from the fastest one-liner fix to deep diagnostic log analysis. Browse all Microsoft fix guides →

The Quick Fix, Try This First

Before you spend an hour digging through logs, run through this rapid triage. About 60% of Azure Blob Storage access problems come down to one of these three things: an expired SAS token, a storage account firewall rule, or a missing RBAC role assignment. Let's knock these out fast.

Step 1, Regenerate and verify your connection string or SAS token. In the Azure portal, navigate to your storage account → Security + networkingAccess keys. Copy the full connection string for key1 and test it directly using Azure Storage Explorer. If that works, your application's connection string is stale, update it in your app config or Key Vault secret.

If you're using a SAS token, check the expiry. Paste your SAS URI into this PowerShell snippet to decode it instantly:

# Decode SAS token expiry, paste your full SAS URI between the quotes
$sas = "https://youraccount.blob.core.windows.net/container/blob?sv=2022-11-02&se=2026-01-01T00%3A00%3A00Z&..."
[System.Web.HttpUtility]::UrlDecode(($sas -split 'se=')[1] -split '&')[0]

Step 2, Check your storage account firewall. Go to your storage account → Security + networkingNetworking. If "Enabled from selected virtual networks and IP addresses" is selected, your client IP or the service's outbound IP must be in the allowlist. Click Add your client IP address to add yourself immediately and test. For Azure services like Functions or App Service, you need either a VNet integration or "Allow Azure services on the trusted services list to access this storage account" checked.

Step 3, Verify RBAC role assignments. Go to your storage account → Access Control (IAM)Check access → search for the user, managed identity, or service principal. They need at minimum Storage Blob Data Reader for read operations, or Storage Blob Data Contributor for write operations. Owner/Contributor roles at the subscription level do NOT grant data-plane access, this surprises a lot of people.

Pro Tip
When you're diagnosing a 403 error, look at the error code in the response body, not just the HTTP status. AuthorizationPermissionMismatch means the identity exists but lacks the right data-plane role. AuthorizationFailure usually points to a bad key or expired token. PublicAccessNotPermitted means anonymous access was disabled at the account level. Each one has a completely different fix, and reading just the 403 status wastes valuable time.
1
Enable and Read Azure Storage Diagnostic Logs

You cannot troubleshoot Azure Storage blobs blind. The single highest-leverage action you can take is turning on Storage Analytics logging (or Azure Monitor resource logs) and reading what Azure is actually recording about every request. I've seen teams spend days guessing when the answer was sitting right there in the logs.

Navigate to your storage account → MonitoringDiagnostic settings+ Add diagnostic setting. Check StorageRead, StorageWrite, and StorageDelete under the Blob category, then send logs to a Log Analytics workspace. Click Save.

Once logs are flowing (allow 5–10 minutes for the first entries), go to MonitoringLogs and run this Kusto query to surface failed requests:

StorageBlobLogs
| where TimeGenerated > ago(1h)
| where StatusCode != 200 and StatusCode != 201 and StatusCode != 206
| project TimeGenerated, OperationName, StatusCode, StatusText, ErrorCode, CallerIpAddress, Uri
| order by TimeGenerated desc
| take 100

The ErrorCode column is your gold mine. Values like BlobNotFound, AuthorizationPermissionMismatch, RequestRateTooHigh, or BlobArchived tell you exactly what's failing. Pair the Uri column with CallerIpAddress to confirm which client and which blob path is triggering the error.

If you're using the older $logs blob container format (Storage Analytics v1), you can download logs directly via Azure Storage Explorer by navigating to the $logs container in your storage account. The log format there is pipe-delimited and less readable, but the error codes are identical.

What you should see if this worked: A list of failed requests with specific error codes. Even a single row is actionable, it tells you exactly which operation is failing and from which IP or identity.

2
Fix Authentication and Authorization Errors (401 / 403)

Authentication errors on Azure Storage blobs come in flavors that look identical from the outside but need completely different fixes. Here's how to split them apart.

If you see HTTP 401 with error code NoAuthenticationInformation: The request arrived without any credentials at all. Your connection string is missing, your SAS token wasn't appended to the URL, or your Managed Identity wasn't properly granted tokens. Verify the application is actually reading the connection string from the right environment variable or Key Vault reference.

If you see HTTP 403 with AuthorizationPermissionMismatch: The identity authenticated fine but doesn't have a data-plane RBAC role. Run this PowerShell to check current role assignments:

# Replace with your storage account resource ID
$scope = "/subscriptions/{sub-id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}"
Get-AzRoleAssignment -Scope $scope | Select-Object DisplayName, RoleDefinitionName, PrincipalType

Assign the correct role if it's missing:

New-AzRoleAssignment `
  -ObjectId "{managed-identity-object-id}" `
  -RoleDefinitionName "Storage Blob Data Contributor" `
  -Scope $scope

If you see HTTP 403 with AccountIsDisabled: The storage account itself is disabled. Go to your storage account → Overview and check the status. This is rare but happens after policy enforcement in enterprise environments.

If Shared Key authentication was disabled: Azure now allows disabling Shared Key auth at the account level (a security feature). If your app uses a connection string with AccountKey, it will fail with KeyBasedAuthenticationNotPermitted. Go to Configuration → scroll to "Allow storage account key access" → enable it, or migrate your app to use Managed Identity instead, which is the right long-term fix anyway.

What you should see if this worked: Requests succeed with HTTP 200/201. Rerun your diagnostic log query, the 403 rows should stop appearing.

3
Resolve Blob and Container Not Found Errors (404)

A 404 on Azure Blob Storage sounds simple, the blob doesn't exist. But in practice, there are five distinct scenarios that all produce a 404, and only one of them means the blob is actually gone.

Scenario A, Wrong container name or blob path: Azure blob paths are case-sensitive. MyContainer/MyBlob.jpg and mycontainer/myblob.jpg are completely different paths. Double-check casing end-to-end. Run this to list exactly what exists:

az storage blob list \
  --account-name "yourstorageaccount" \
  --container-name "yourcontainer" \
  --output table \
  --auth-mode login

Scenario B, Soft delete is on, blob appears missing: If soft delete is enabled and a blob was deleted within the retention period, it still exists but is hidden. In Azure Storage Explorer, click ViewActive and soft-deleted blobs to reveal them. You can undelete with:

az storage blob undelete \
  --account-name "yourstorageaccount" \
  --container-name "yourcontainer" \
  --name "your-blob-name" \
  --auth-mode login

Scenario C, Blob in Archive tier: Archive tier blobs return BlobArchived (which some SDKs surface as a 409, others as a 404). You must rehydrate first. Set the rehydration priority to High for urgent data:

az storage blob set-tier \
  --account-name "yourstorageaccount" \
  --container-name "yourcontainer" \
  --name "your-blob-name" \
  --tier Hot \
  --rehydrate-priority High \
  --auth-mode login

Rehydration can take between 1 and 15 hours depending on blob size. There's no way to speed it up beyond setting High priority.

Scenario D, Container doesn't exist yet: Your app is trying to upload before the container was created. Add container creation logic with CreateIfNotExists() in your SDK code, or create it manually via the portal under Data storageContainers+ Container.

What you should see if this worked: The blob is accessible, the undelete succeeds, or the rehydration status changes to "rehydrate-pending."

4
Fix Throttling, 503 Errors, and RequestRateTooHigh

If your application is hammering Azure Blob Storage with thousands of requests per second, you'll eventually hit the scalability limits. The response is usually HTTP 503 with error code ServerBusy or HTTP 429 with RequestRateTooHigh. I know it's tempting to just retry harder, don't. That makes it worse.

First, understand the limits you're working with. A Standard general-purpose v2 storage account supports up to 20,000 requests per second, 10 Gbps ingress, and 50 Gbps egress per storage account. Premium block blob accounts have higher IOPS but the same per-request rate limits apply per partition.

Check your current metrics by going to your storage account → MonitoringMetrics. Add these metrics to a chart:

  • Transactions, total request count over time
  • Availability, should be 100%; dips correlate with throttling events
  • Success E2E Latency vs Success Server Latency, a big gap between these two points to client-side network issues, not server throttling

Implement exponential backoff with jitter in your application code. The Azure Storage SDK does this automatically when you use the built-in retry policies. If you're using the .NET SDK, configure it like this:

var options = new BlobClientOptions();
options.Retry.MaxRetries = 5;
options.Retry.Delay = TimeSpan.FromSeconds(2);
options.Retry.MaxDelay = TimeSpan.FromSeconds(60);
options.Retry.Mode = Azure.Core.RetryMode.Exponential;

var client = new BlobServiceClient(connectionString, options);

If you're consistently hitting limits, the right architectural fix is to distribute load across multiple storage accounts, use Azure CDN or Front Door in front of your blob endpoint for read-heavy workloads, or batch small write operations using block blob staging (put block + put block list) rather than individual put blob calls for every file.

What you should see if this worked: The Availability metric returns to 100%, Success E2E Latency stabilizes, and your application logs stop showing 503 or 429 responses.

5
Troubleshoot Network Rules, Firewall, and CORS Errors

Network-level blocks are sneaky because they often look like authentication failures or complete timeouts, not firewall rejections. If your app works fine from your laptop but fails when deployed to Azure App Service, Azure Functions, or a VM, firewall rules are almost always the answer.

For Azure service-to-service connectivity: Go to your storage account → Networking → under "Exceptions," make sure "Allow Azure services on the trusted services list to access this storage account" is checked. App Service, Functions, Logic Apps, and Azure Data Factory are all on this trusted list. This single checkbox has saved me from more production outages than I can count.

For VNet-integrated services: If your App Service or Function is VNet-integrated, you need to add the subnet to the storage account's allowed virtual networks. Under NetworkingVirtual networks+ Add existing virtual network, select the VNet and subnet. Make sure the subnet has the Microsoft.Storage service endpoint enabled.

# Enable service endpoint on the subnet via PowerShell
$subnet = Get-AzVirtualNetworkSubnetConfig -Name "your-subnet" -VirtualNetwork (Get-AzVirtualNetwork -Name "your-vnet" -ResourceGroupName "your-rg")
$subnet.ServiceEndpoints = @()
$endpoint = New-AzServiceEndpointPolicyDefinition -Name "StorageEndpoint" -Service "Microsoft.Storage"
# Then update the VNet with the endpoint enabled

For CORS errors, if you're building a web app that calls blob endpoints directly from the browser, you need CORS configured on the storage account. Go to SettingsResource sharing (CORS) → select Blob service+ Add. Fill in:

  • Allowed origins: Your domain (e.g., https://yourapp.com), never use * in production for writable endpoints
  • Allowed methods: GET, PUT, DELETE, HEAD, OPTIONS
  • Allowed headers: *
  • Exposed headers: *
  • Max age: 3600

CORS errors show up in the browser console as Access to fetch at 'https://youraccount.blob.core.windows.net/...' from origin 'https://yourapp.com' has been blocked by CORS policy. After saving the CORS rule, test with a curl preflight:

curl -I -X OPTIONS "https://youraccount.blob.core.windows.net/yourcontainer/yourblob" \
  -H "Origin: https://yourapp.com" \
  -H "Access-Control-Request-Method: GET"

You should see Access-Control-Allow-Origin: https://yourapp.com in the response headers. If you don't, the CORS rule didn't save correctly or the origin doesn't match exactly (trailing slash, http vs https, subdomain, all matter).

What you should see if this worked: Requests from your deployed service reach the storage account without timeout, and browser preflight requests return valid CORS headers.

Advanced Troubleshooting

If the steps above haven't cracked it, you're dealing with something deeper. Here's where I go when the standard fixes don't land.

Analyzing Event Viewer and Application Logs for SDK Errors

When your application is running on a Windows server or Azure VM, open Event Viewer (eventvwr.msc) → Windows LogsApplication. Filter by your application's source and look for entries around the time of blob failures. The Azure Storage SDK logs detailed exception traces including the RequestId, a GUID you can cross-reference directly in your Storage diagnostic logs to find the exact failed request on the server side.

Blob Lease Conflicts, Breaking Stuck Leases

If you're seeing HTTP 409 with error code LeaseAlreadyPresent or LeaseIdMissing, a blob is locked. This usually happens when an application crashed mid-operation. You can break the lease forcibly using PowerShell:

# Install Az.Storage module if needed: Install-Module Az.Storage
$ctx = New-AzStorageContext -StorageAccountName "youraccount" -UseConnectedAccount
$blob = Get-AzStorageBlob -Container "yourcontainer" -Blob "your-locked-blob.txt" -Context $ctx

# Break the lease, no lease ID needed for a forced break
$blob.ICloudBlob.BreakLease([TimeSpan]::Zero)

After breaking the lease, the blob returns to an unlocked state immediately and normal write operations can proceed.

Enterprise and Domain-Joined Scenarios

In enterprise environments, Azure Storage Blobs are often accessed through Azure Private Endpoints, meaning the storage account's public endpoint is completely disabled. If your application is using the public DNS name (youraccount.blob.core.windows.net) but the storage account only accepts connections via private endpoint, every request will fail with a timeout or connection refused, not a meaningful error.

Verify with: nslookup youraccount.blob.core.windows.net. If it resolves to a 10.x.x.x or 172.x.x.x private IP, you're going through a private endpoint and your client must be on the same VNet or connected via ExpressRoute/VPN. If it resolves to a public Azure IP but connections are failing, check if Public network access is set to "Disabled" under Networking.

Group Policy and Conditional Access

In Azure AD-integrated environments, Conditional Access policies can block token issuance for storage access. Check the Azure AD Sign-in logs (Azure Active DirectoryMonitoringSign-in logs) and filter by the service principal or user identity making the storage calls. A Conditional Access failure shows as Status: Failure with the specific policy name listed under Conditional Access.

Immutable Storage and Legal Hold Conflicts

If you're getting HTTP 409 with BlobImmutableDueToPolicy, the container has an immutability policy or legal hold active. These are intentional, you cannot delete or overwrite blobs until the policy expires or the hold is released. Go to Data storageContainers → select your container → Access policy to review active policies.

When to Call Microsoft Support
Escalate to Microsoft Support if: your storage account shows degraded availability in the Azure Service Health dashboard (indicating a platform-side incident), you're seeing unexplained data corruption where blob content doesn't match what was uploaded (verify with MD5 hash checking), or you've confirmed all configuration is correct but requests still fail with 500 InternalError responses. Open a support ticket with Severity A if production data is inaccessible, include your storage account resource ID, the specific error codes from diagnostic logs, and the request IDs of failed transactions.

Checking Storage Account Health via Azure Service Health

Before spending hours diagnosing what might be an Azure platform incident, always check Azure Service HealthService issues and filter by region and the Azure Storage service. Platform-side degradation events happen occasionally and no amount of configuration changes will fix them, you just have to wait. Set up a Service Health alert so you get email or webhook notifications for future events.

Prevention & Best Practices

Most Azure Blob Storage problems are preventable. The issues I troubleshoot most often aren't caused by Azure itself, they're caused by apps that weren't built with storage failures in mind, or accounts that were configured once and never reviewed again. Here's how to stay ahead of it.

Use Managed Identity everywhere you can. Connection strings with account keys are a security and operational liability. Keys expire, rotate, and get accidentally committed to git repositories. Managed Identity eliminates all of that, your Azure service gets a token automatically, and RBAC controls what it can do. There's no key to expire or rotate manually. Migrate your apps to Managed Identity now, not after your next production incident.

Set up Storage metrics alerts. Go to your storage account → MonitoringAlerts+ Create. Configure alerts for: Availability dropping below 99.9%, E2E latency exceeding 1000ms, and the RequestRateTooHigh error count exceeding zero. These alerts catch throttling and availability issues before your users do.

Always implement retry logic with exponential backoff. Azure Storage is a distributed system, transient failures happen. Any code that calls blob storage without retry logic will fail unpredictably in production. Use the built-in retry policies in the Azure SDK rather than writing your own, they're battle-tested and handle the edge cases you haven't thought of yet.

Review and test your network access rules quarterly. Firewall rules and private endpoints are easy to configure but easy to forget. When you add a new service, VNet, or deploy to a new region, storage access rules need to be updated. Build a quarterly review into your operational calendar.

Enable soft delete and versioning. These are your safety nets against accidental deletion and overwrites. Soft delete retains deleted blobs for a configurable period (7–365 days). Versioning automatically preserves previous blob states. Both can be enabled under Data managementData protection. The storage cost is marginal; the data recovery capability is invaluable.

Quick Wins

Frequently Asked Questions

Why am I getting a 403 error on Azure Blob Storage even though I'm the storage account owner?

This is one of the most common gotchas in Azure. Being the Owner or Contributor on the storage account resource grants you management-plane access, meaning you can configure the account, change settings, create containers. It does not automatically grant data-plane access to read and write blobs. For that, you need an explicit data-plane role like Storage Blob Data Owner, Storage Blob Data Contributor, or Storage Blob Data Reader. Go to Access Control (IAM)+ Add role assignment and assign one of these roles to yourself. Alternatively, if you're accessing via the Azure portal's Storage Browser, your Azure AD user needs the data-plane role, the portal doesn't fall back to account keys for browser-based access.

My SAS token stopped working, how do I tell if it's expired vs. something else?

Decode the se= parameter in your SAS URI, that's the signed expiry time in ISO 8601 format (e.g., se=2026-04-20T12%3A00%3A00Z). URL-decode it and compare to UTC time right now. If it's in the past, it's expired, generate a new one. If it's still valid, look at the sp= parameter (signed permissions) and make sure the permission your app needs is included: r for read, w for write, d for delete, l for list. Also check the spr= parameter, if it says spr=https and your app is making HTTP requests, the SAS will be rejected. One more thing: if the storage account's Shared Key authentication was disabled after the SAS was generated, all key-based SAS tokens become invalid instantly regardless of expiry time.

How do I fix "The specified resource does not exist" (BlobNotFound) when I can see the blob in the portal?

The most common cause is a case sensitivity mismatch. Azure blob names and container names are case-sensitive, Reports/Q1-Summary.xlsx and reports/q1-summary.xlsx are entirely different paths. Copy the exact path from the portal's Storage Browser (right-click the blob → Properties → URL) and compare it character-by-character to what your application is constructing. A second common cause: you're looking at the blob through a different storage account. If you have multiple storage accounts in your subscription, confirm the account name in your connection string matches the one showing the blob in the portal. Finally, if blob versioning is enabled, your SDK might be retrieving a specific version ID that no longer exists as a current version, omit the version ID parameter to get the current version.

Azure Blob upload is stuck or extremely slow, what causes this and how do I speed it up?

Slow uploads almost always come down to one of three things. First, check your storage account's region, if your application is in East US and your storage account is in West Europe, you're paying a cross-region latency penalty of 80–150ms per request, which adds up catastrophically for large files or many small files. Always co-locate your storage account with the compute that writes to it. Second, if you're uploading large files (over 100MB) using a single Put Blob call, switch to parallel block uploads using Put Block + Put Block List, the .NET SDK's UploadAsync with StorageTransferOptions does this automatically when you set MaximumTransferSize and MaximumConcurrency. Third, verify you're not going through a proxy or VPN that throttles outbound bandwidth, test upload speed directly from the same network path your application uses.

How do I list all blobs in a container when there are millions of them without timing out?

Never try to list millions of blobs in a single call, the operation will time out and you'll get partial results. Use paginated listing with a continuation token. In the Azure CLI: az storage blob list --account-name youraccount --container-name yourcontainer --num-results 5000 --query "[].name" --auth-mode login and use --marker with the next-marker value for subsequent pages. In .NET, use GetBlobsAsync() which returns an AsyncPageable<BlobItem>, iterate with await foreach and it handles pagination automatically. For truly massive containers (tens of millions of blobs), use Azure Data Factory or Blob Inventory to generate a manifest file rather than real-time listing, inventory reports are generated server-side and delivered as a CSV or Parquet file to a destination container without any client-side timeout risk.

I deleted a blob by accident, can I get it back?

Maybe, it depends entirely on whether soft delete was enabled before the deletion happened. Go to your storage account → Data managementData protection and check if "Enable soft delete for blobs" was on. If yes, open Azure Storage Explorer, connect to your account, right-click your container, and choose ViewActive and soft-deleted blobs. Right-click the deleted blob (shown with a strikethrough or a different icon) and select Undelete. If soft delete was not enabled, the blob is gone permanently, Azure does not keep backup copies unless you explicitly configured blob versioning or a backup policy through Azure Backup for Storage. This is why enabling soft delete before you need it is so important.

Related Microsoft Fix Guides

H
Sai Kiran Pandrala
Our team includes certified Microsoft engineers, Azure architects, and system administrators with 10+ years of enterprise IT experience. Every guide is written from hands-on troubleshooting, not guesswork. We test every fix before publishing.