Azure Blob Storage: Fix Common Setup & Config Errors

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

Why This Is Happening

I've worked through dozens of Azure Blob Storage setups gone sideways, and the pattern is almost always the same: someone follows what looks like a straightforward process , create a storage account, drop some files in a container, point an app at it , and then something quietly breaks. A 403 flies back from the REST API. Blobs show up in the portal but won't download. An upload that worked yesterday now times out. And Microsoft's error messages? Often just generic enough to be useless.

Azure Blob Storage is Microsoft's object storage platform built for the cloud. It's designed to hold massive amounts of unstructured data, images, videos, log files, backups, binary payloads, you name it. The service is genuinely powerful. But "powerful" often means "a lot of knobs to get wrong." Authentication alone has four different models: shared key, shared access signatures (SAS), Azure Active Directory (Microsoft Entra ID), and anonymous public access. Misconfigure any one of them and you get a wall of 401s or 403s with no real explanation of which layer is rejecting you.

Here's what makes Azure Blob Storage setup problems particularly frustrating: the portal happily lets you configure things that will silently fail later. You can set a lifecycle management policy that immediately moves blobs to archive tier, then wonder why your app can't read them anymore (archived blobs aren't directly readable; you have to rehydrate them first). You can enable a storage account firewall without whitelisting your own IP and lock yourself out completely. You can generate a SAS token with a one-hour expiry, go to lunch, come back, and watch every request fail with AuthenticationFailed.

The Azure Blob Storage service itself operates across three storage tiers, hot, cool, and archive, and blobs can move between them automatically via lifecycle policies. That's great for cost management, but if your lifecycle policy is misconfigured, you'll start seeing access errors that look like permission issues but are actually tier-access issues. Archive-tier blobs return HTTP 409 with error code BlobArchived when you try to read them directly.

Setup problems also spike in enterprise environments. If your storage account sits behind a virtual network, your developer's local machine might be blocked by the storage firewall even though your Azure VM can reach it fine. DNS resolution for custom domains on static website hosting is another classic pain point. CORS headers missing from blob responses break browser-based apps in ways that look like network failures rather than configuration errors.

The good news: almost every Azure Blob Storage configuration error has a specific fix. This guide walks you through the most common ones, from the five-minute quick wins to the deep enterprise-level troubleshooting. Browse all Microsoft fix guides →

The Quick Fix, Try This First

Before going deep into diagnostics, check these three things. In my experience, one of them resolves the problem about 60% of the time.

1. Verify your connection string is current. Go to the Azure portal, open your storage account, and navigate to Security + networking → Access keys. Copy the full connection string for key1. It looks like this:

DefaultEndpointsProtocol=https;AccountName=youraccount;AccountKey=BASE64KEY==;EndpointSuffix=core.windows.net

Paste it directly into your app's configuration and test again. A huge percentage of Azure Blob Storage connection failures come from a stale or truncated connection string, someone copied it with a trailing space, or the key was rotated and the app config wasn't updated.

2. Check the storage account firewall. In the portal, go to Security + networking → Networking. If "Enabled from selected virtual networks and IP addresses" is selected, your machine's public IP needs to be listed under Firewall → Address range. If you just need to test quickly, temporarily switch to "Enabled from all networks", but put the restriction back afterward.

3. Confirm container public access level. Navigate to your storage account → Data storage → Containers, click your container, then Change access level. For anonymous blob reads, you want "Blob (anonymous read access for blobs only)" or "Container (anonymous read access for containers and blobs)." If it says "Private," unauthenticated requests will always get a 404 (not a 403, Azure deliberately hides private container existence from anonymous callers).

If none of those three solve it, your problem is likely authentication, CORS, tier access, or a network-level block. Keep reading, I've got the full step-by-step below.

Pro Tip
Azure Storage Explorer (a free Microsoft desktop app) is the fastest way to test blob access independently of your code. If Storage Explorer can connect and browse blobs but your app can't, the problem is in your app's auth configuration, not the storage account itself. If Storage Explorer also fails, the problem is account-level.
1
Diagnose the Exact Error, Read the HTTP Response Body

Azure Blob Storage errors are not just HTTP status codes. The response body contains a structured XML error that tells you exactly what went wrong. Most developers see the 403 or 404, stop there, and start guessing. Don't do that.

Use PowerShell or Azure CLI to make a raw request and capture the full response body. With the Azure CLI:

az storage blob show \
  --account-name youraccount \
  --container-name yourcontainer \
  --name yourblob.txt \
  --account-key "YOUR_ACCOUNT_KEY"

Or, to see raw HTTP details, use curl with a SAS URL:

curl -v "https://youraccount.blob.core.windows.net/yourcontainer/yourblob.txt?YOUR_SAS_TOKEN" 2>&1 | head -80

The XML error body will contain an error code like AuthenticationFailed, BlobNotFound, PublicAccessNotPermitted, BlobArchived, or ConditionNotMet. Each of these points to a completely different fix path:

  • AuthenticationFailed → SAS token expired or shared key is wrong
  • BlobNotFound → blob name casing mismatch (blob names are case-sensitive) or wrong container
  • PublicAccessNotPermitted → the storage account has public blob access disabled at the account level
  • BlobArchived → blob is in archive tier and needs rehydration before reading
  • AuthorizationFailure → RBAC role missing, user doesn't have the right Azure role assignment

Once you know the exact error code, you know exactly what to fix. If you see the correct blob content returned, the issue is upstream, a proxy, CDN, or DNS problem.

2
Fix Authentication, Shared Key, SAS Token, and Microsoft Entra ID

Azure Blob Storage supports multiple authorization methods, and mixing them up is one of the most common Azure Blob Storage configuration errors I've seen in real deployments. Here's how to get each one working correctly.

Shared Key (Account Key): This is the nuclear option, it grants full access to everything in the account. It should only be used for trusted, server-side services. If your 401 or 403 is happening with shared key auth, double-check that the key hasn't been rotated. In the portal: Storage account → Security + networking → Access keys → Show keys. You have two keys; if key1 was rotated, try key2. Then rotate back properly using a zero-downtime key rotation procedure.

SAS Token (Shared Access Signature): SAS tokens have an expiry time, a set of allowed services, resource types, and permissions baked directly into the URL. A common failure mode is generating a SAS from your local machine in UTC+5 while the token's start time is set to "now", Azure's servers see a start time in the future and reject the token immediately. Always set your SAS start time to at least 15 minutes in the past to account for clock skew.

Generate a corrected SAS via Azure CLI:

az storage account generate-sas \
  --account-name youraccount \
  --account-key "YOUR_KEY" \
  --expiry 2026-05-01T00:00:00Z \
  --https-only \
  --permissions acdlruw \
  --resource-types sco \
  --services b

Microsoft Entra ID (formerly Azure AD): For production apps, this is the right approach. Your app gets an OAuth token and presents it as a Bearer header. If you're seeing AuthorizationFailure with Entra auth, the issue is almost always a missing RBAC role assignment. In the portal: Storage account → Access Control (IAM) → Add role assignment. Assign Storage Blob Data Contributor (or Reader for read-only) to your app's managed identity or service principal.

After adding the role, allow up to 5 minutes for Azure's RBAC propagation before retesting.

3
Fix CORS Errors for Browser-Based Azure Blob Storage Access

If your web app is trying to read or upload blobs directly from the browser, not through a server backend, you will hit CORS issues unless you configure them explicitly. The browser error typically looks like:

Access to fetch at 'https://youraccount.blob.core.windows.net/...' 
from origin 'https://yourapp.com' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

Azure Blob Storage CORS rules are set per storage service (Blob, File, Queue, Table) and live on the storage account itself, not on individual containers. To fix this:

In the Azure portal, go to: Storage account → Settings → Resource sharing (CORS). Click the Blob service tab and add a new CORS rule. For development, a permissive rule looks like:

Allowed origins:  *
Allowed methods:  DELETE, GET, HEAD, MERGE, OPTIONS, PATCH, POST, PUT
Allowed headers:  *
Exposed headers:  *
Max age (seconds): 3600

For production, replace the wildcard origin with your actual domain: https://yourapp.com. Multiple origins can be added as separate rows.

You can also set this via Azure CLI:

az storage cors add \
  --account-name youraccount \
  --account-key "YOUR_KEY" \
  --services b \
  --methods DELETE GET HEAD MERGE OPTIONS PATCH POST PUT \
  --origins "https://yourapp.com" \
  --allowed-headers "*" \
  --exposed-headers "*" \
  --max-age 3600

One thing to verify: CORS preflight requests (HTTP OPTIONS) need to succeed. If your storage account firewall is blocking the preflight from the user's browser IP, you'll get a network error before CORS even kicks in. Always test in browser DevTools, the Network tab's failed OPTIONS request tells you whether it's a CORS rule problem or a firewall block.

4
Rehydrate Archive-Tier Blobs You Can't Read

This one surprises people every time. Azure Blob Storage has three access tiers, hot, cool, and archive. Hot and cool are online tiers: blobs are immediately readable. Archive is an offline tier. When a blob is in archive, any attempt to read it returns HTTP 409 with error code BlobArchived. The blob still shows up in the container listing, but it can't be streamed or downloaded until you rehydrate it.

Rehydration means copying the blob back to hot or cool tier. There are two ways to do this:

Option A, Change the blob's access tier directly:

az storage blob set-tier \
  --account-name youraccount \
  --container-name yourcontainer \
  --name yourblob.txt \
  --tier Hot \
  --rehydrate-priority Standard

Standard rehydration takes up to 15 hours. If you need the blob urgently, use --rehydrate-priority High, that gets you the blob within 1 hour for blobs under 10 GB, but costs more.

Option B, Copy the blob to a new location at hot tier:

az storage blob copy start \
  --account-name youraccount \
  --destination-container hotcontainer \
  --destination-blob yourblob.txt \
  --source-account-name youraccount \
  --source-container archivecontainer \
  --source-blob yourblob.txt \
  --tier Hot

The original archived blob stays where it is. The copy lands in hot tier and is immediately readable.

To prevent this from happening again, check your lifecycle management policies: Storage account → Data management → Lifecycle management. Look for any rules that move blobs to archive tier. If the policy is too aggressive, moving blobs after just a few days, increase the threshold to match your actual access patterns. Any blob your app regularly reads should stay on hot or cool tier.

5
Fix Azure Blob Storage Static Website Hosting Issues

Azure Blob Storage includes a static website hosting feature that serves your HTML, CSS, and JavaScript files directly from a $web container. It's genuinely useful, but the configuration has some specific gotchas that catch almost everyone the first time.

Enable static website hosting first: Go to Storage account → Data management → Static website. Toggle to Enabled. Set your index document name (usually index.html) and your 404 error document path (usually 404.html or index.html for single-page apps). Click Save. Azure will then create a $web container automatically, upload your files there.

Your site is served from a URL like: https://youraccount.z13.web.core.windows.net/, not from the standard blob endpoint. This is a common source of confusion. Files in $web accessed via the blob endpoint require authentication; accessed via the static website endpoint they're public.

Custom domain HTTPS: If you're mapping a custom domain and need HTTPS, you can't just add a CNAME, Azure Blob Storage static websites don't natively support custom-domain HTTPS. The standard solution is to put Azure CDN in front of it: Storage account → Security + networking → Azure CDN. Create a CDN endpoint pointed at the static website origin, then map your custom domain to the CDN endpoint. The CDN handles TLS termination.

SPA routing 404s: If your React or Vue app uses client-side routing and you get 404s on direct URL loads (like navigating to /about), set your 404 error document to index.html. Azure will serve index.html for any path it can't find, letting your router take over. This is the standard SPA fix for Azure Blob Storage static website hosting.

After uploading new files, if you see old content in the browser, a cache-control header issue may be the culprit. Set Cache-Control: no-cache on your HTML files during the blob upload:

az storage blob upload-batch \
  --account-name youraccount \
  --destination '$web' \
  --source ./dist \
  --content-cache-control "no-cache" \
  --pattern "*.html"

Advanced Troubleshooting

When the basic fixes don't cut it, you're usually dealing with network-level blocks, enterprise identity configurations, or subtle account-level settings that override everything else. Here's where to dig.

Azure Storage Firewall and Virtual Network Service Endpoints: If your storage account is locked down to specific virtual networks and your app runs outside those networks, or on a different subnet than expected, every request gets silently dropped. In the portal: Storage account → Security + networking → Networking → Firewalls and virtual networks. Scroll through the listed virtual networks and subnets. If your app's subnet isn't listed, add it. For apps running on Azure VMs or App Service, make sure the subnet has the Microsoft.Storage service endpoint enabled:

az network vnet subnet update \
  --resource-group yourRG \
  --vnet-name yourVNet \
  --name yourSubnet \
  --service-endpoints Microsoft.Storage

Enabling Azure Storage Logging for Diagnosis: Azure Storage has built-in logging that captures every request, including the exact auth error. Enable it via: Storage account → Monitoring → Diagnostic settings → Add diagnostic setting. Send StorageRead, StorageWrite, and StorageDelete logs to a Log Analytics workspace. Then query them:

StorageBlobLogs
| where StatusCode == 403 or StatusCode == 401
| project TimeGenerated, CallerIpAddress, AuthenticationType, StatusCode, StatusText, ErrorCode, Uri
| order by TimeGenerated desc
| take 50

This query surfaces who was trying to access what, from which IP, with which auth method, and what exact error they got. It cuts diagnosis time from hours to minutes.

Redundancy Configuration Errors: Azure Blob Storage offers several redundancy options, LRS, ZRS, GRS, GZRS. If your app expects geo-redundant reads from the secondary endpoint (-secondary.blob.core.windows.net) but your account is LRS, those reads will always fail. Check your redundancy setting: Storage account → Data management → Redundancy. Secondary endpoint reads also require Read-access geo-redundant storage (RA-GRS or RA-GZRS) specifically, GRS alone doesn't enable secondary reads.

SFTP and NFS 3.0 Access Failures: Azure Blob Storage supports SFTP access and NFS 3.0 container mounting (primarily for Linux environments). Both require hierarchical namespace to be enabled on the account, which is part of Azure Data Lake Storage Gen2. You can't enable hierarchical namespace after account creation; the account must be created with it on. If you're getting errors trying to mount via NFS or connect via SFTP, and hierarchical namespace is off, you'll need to migrate data to a new account created with hierarchical namespace enabled.

BlobFuse2 Mount Issues on Linux: BlobFuse2 lets you mount Azure Blob Storage containers as a local filesystem on Linux. Common mount failure: the blobfuse2 mount command returns mount failed: exit status 1 with no other detail. Check /var/log/syslog or journalctl -u blobfuse2 for the actual error. Most failures are either a bad config file path or missing FUSE kernel module, run sudo modprobe fuse first.

When to Call Microsoft Support

If you've worked through everything above and still have unexplained failures, especially if logs show successful auth but requests still fail, or if you're seeing data inconsistencies after a regional outage, it's time to open a support ticket. Azure Storage has an internal service health layer that isn't always reflected on the Azure Status page immediately. Microsoft Support can check whether there's an active incident on your specific storage account's underlying infrastructure. Go to your Azure portal → Help + support → Create a support request, select the affected storage account as the resource, and choose "Technical" as the issue type. Have your storage account name, resource group, region, and example request timestamps ready, it speeds things up significantly.

Prevention & Best Practices

Most Azure Blob Storage problems are preventable. After fixing things reactively for years, here's what I've learned to set up proactively on every new storage account before anything goes wrong.

Never share account keys in application code. Account keys give unrestricted access to everything in the storage account. Store them in Azure Key Vault and reference them from Key Vault in your app. Better still, switch to managed identity authentication entirely, your app running on Azure (App Service, Azure Functions, VMs) can authenticate to Blob Storage without any stored credentials at all. This eliminates a whole class of credential-leak and key-rotation problems.

Plan your access tier strategy before writing data. Hot tier is for data accessed frequently. Cool tier saves money for data accessed less than once a month but still needs to be online. Archive tier is for data you don't expect to read for months or years, and rehydration costs time and money. Set your lifecycle policies thoughtfully, and test them in a staging account first. An overly aggressive archive policy that kicks in after 7 days will break any app that assumes blobs are always online-readable.

Set up Azure Monitor alerts on your storage account. At minimum, configure alerts for: 4xx error rate spike, storage account capacity approaching quota, and authentication failure rate exceeding baseline. These alerts give you early warning before a configuration problem becomes a production outage.

Use separate containers for separate access control needs. Azure Blob Storage access policies apply at the container level. If you mix public blobs and private blobs in the same container, you can't set granular policies, you'd have to use SAS tokens on every private blob individually. Keep public assets in one container (access level: Blob) and private data in separate containers (access level: Private) with RBAC-controlled access.

Test your SAS tokens immediately after generating them. SAS tokens have time windows, IP restrictions, and protocol constraints baked in. Generate one, then immediately test it with curl before embedding it in your app. A bad SAS token generated by a clock-skewed machine will fail instantly in production but not during local testing.

Quick Wins
  • Enable soft delete for blobs (Data protection → Enable soft delete for blobs), gives you a recovery window if blobs are accidentally deleted
  • Enable blob versioning for any container holding important documents, every write creates a recoverable version
  • Set a minimum TLS version of TLS 1.2 on the storage account (Configuration → Minimum TLS version) to block outdated clients
  • Disable shared key access on storage accounts where you only need Entra ID authentication, this forces all access through RBAC and eliminates key-compromise risk entirely

Frequently Asked Questions

What exactly is Azure Blob Storage and what is it designed to store?

Azure Blob Storage is Microsoft's object storage service for the cloud, built specifically for unstructured data, meaning anything that doesn't fit neatly into rows and columns. That includes images, videos, audio files, log files, backups, archives, and raw binary data. It's designed for scenarios like serving files directly to browsers, streaming media, storing application logs, holding disaster recovery backups, and feeding data into analytics pipelines. Objects are accessible from anywhere via HTTP or HTTPS, and Microsoft provides client SDKs for .NET, Java, Python, Node.js, and more so you don't have to hand-craft REST requests.

Why am I getting a 403 Forbidden error when accessing Azure Blob Storage?

A 403 on Azure Blob Storage almost always means one of four things: your SAS token has expired or has insufficient permissions, your Azure RBAC role assignment is missing or hasn't propagated yet (allow up to 5 minutes), the storage account firewall is blocking your IP, or the storage account has public blob access disabled at the account level. Read the XML error body, not just the HTTP status code. The ErrorCode field inside the response body (like AuthorizationPermissionMismatch or PublicAccessNotPermitted) tells you exactly which layer is rejecting you. Each code points to a different fix.

What is the difference between hot, cool, and archive storage tiers in Azure Blob Storage?

All three tiers store your data durably, but they trade storage cost against access cost differently. Hot tier costs more per GB stored but charges the least for read and write operations, ideal for data you access daily or weekly. Cool tier costs less to store but charges more per access operation, good for data you access maybe once a month or less, like monthly reports. Archive tier is the cheapest storage by far but blobs in archive are offline, you can't read them directly and must rehydrate them to hot or cool first, which takes anywhere from 1 to 15 hours depending on priority. Never put data in archive if your app needs to read it on demand.

How do I fix CORS errors when accessing Azure Blob Storage from a browser?

CORS rules for Azure Blob Storage are set on the storage account itself, not on individual containers or blobs. In the Azure portal, navigate to your storage account, then go to Settings → Resource sharing (CORS), and click the Blob service tab. Add a new rule with your app's origin in the Allowed origins field, all the HTTP methods your app uses in Allowed methods, and asterisks in Allowed headers and Exposed headers for simplicity. Save the rule, then test from the browser, most CORS errors resolve immediately. If the problem persists, check whether your storage firewall is blocking the OPTIONS preflight request from the browser's IP, which will cause a network error before CORS headers are even evaluated.

My blob is in archive tier and I can't read it, how do I get my data back?

You need to rehydrate the blob before it becomes readable again. The two options are: change the blob's access tier directly to hot or cool using az storage blob set-tier --tier Hot --rehydrate-priority Standard (takes up to 15 hours) or High priority (up to 1 hour for blobs under 10 GB, costs more), or copy the blob to a new location at hot tier using az storage blob copy start with --tier Hot. The copy approach lets you read the data in a new location while the original stays in archive. Once rehydrated or copied, reads work normally, you'll stop seeing the HTTP 409 BlobArchived error.

Does Azure Blob Storage support SFTP and NFS access, and why isn't mine working?

Yes, Azure Blob Storage supports both SSH File Transfer Protocol (SFTP) and NFS 3.0 mounting, but both features require the storage account to have hierarchical namespace enabled, which is part of Azure Data Lake Storage Gen2. The catch is that hierarchical namespace must be enabled when the storage account is created, you can't turn it on after the fact for an existing account. If your storage account was created without hierarchical namespace and you're trying to use SFTP or NFS 3.0, you'll need to create a new account with hierarchical namespace enabled and migrate your data there. Once hierarchical namespace is on and SFTP/NFS is enabled in the account settings, both protocols work through the standard Azure Blob Storage endpoint.

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.