Azure Error: 'Server failed to authenticate the request' — Cause, Fix, and Troubleshooting Guide
Fix Azure Storage 'Server failed to authenticate the request': signature mismatch, clock skew, wrong key, expired SAS, or shared-key-disabled accounts.
- #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.
What this error means
Azure Storage returns AuthenticationFailed with the detail Server failed to authenticate the request when the request reached the storage service but the credential attached to it did not validate. The service computed a signature from the request and compared it to the one you sent; they did not match, so the request was rejected before any data was touched. The literal response looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:00000000-1111-2222-3333-444444444444
Time:2026-07-12T14:03:21.7654321Z</Message>
<AuthenticationErrorDetail>The MAC signature found in the HTTP request '...' is not the same as any computed signature.</AuthenticationErrorDetail>
</Error>
The AuthenticationErrorDetail line is the important part — it tells you why the signature failed (bad MAC, expired SAS, disallowed IP, clock skew), and that detail changes the fix.
Where it surfaces
az storage blob upload,azcopy, or an SDK call fails with HTTP 403 andAuthenticationFailed.- The XML body contains
Server failed to authenticate the requestand anAuthenticationErrorDetail. - The same account key works from one machine but fails from another (clock skew), or worked yesterday and fails today (rotated key or expired SAS).
- Portal/Storage Explorer access is fine (it uses your Entra token) while a script using a connection string or SAS fails.
Identity and permission causes
- Wrong or rotated account key. The connection string or
--account-keyuseskey1after the account was rotated tokey2, so every computed MAC differs. - Expired or not-yet-valid SAS token. The
se(expiry) is in the past, orst(start) is in the future, or the machine clock is skewed enough that a valid token reads as expired. - SAS signed for the wrong resource/permission. A blob SAS used against the account/queue endpoint, or a read-only SAS used for a write.
- Client clock skew. Shared-key auth includes a
Date/x-ms-dateheader; if the client clock is more than ~15 minutes off, the signature is rejected. - Shared Key access disabled. The account has
allowSharedKeyAccess=false; only Entra ID (--auth-mode login) auth is accepted, so any key/SAS call fails withAuthenticationFailed. - IP or protocol restriction on the SAS. The SAS has a
siprange orspr=httpsthat the caller violates.
Tracing the failed authorization
Read the AuthenticationErrorDetail first — it distinguishes a MAC mismatch (wrong key) from an expiry (Signature not valid in the specified time frame) from an IP block.
Confirm the account’s current keys and whether shared-key auth is even allowed:
az storage account show \
--name mystorageacct --resource-group data-rg \
--query "allowSharedKeyAccess" -o tsv
az storage account keys list \
--account-name mystorageacct --resource-group data-rg \
--query "[].keyName" -o table
If allowSharedKeyAccess is false, no key or SAS will ever authenticate — you must use Entra ID. Verify your identity has a data-plane role (not just Contributor, which is control-plane only):
az role assignment list \
--assignee "$(az ad signed-in-user show --query id -o tsv)" \
--scope "$(az storage account show -n mystorageacct -g data-rg --query id -o tsv)" \
--query "[].roleDefinitionName" -o table
Check your local clock against a reference — skew is a classic cause:
date -u
timedatectl status 2>/dev/null | grep -i "synchronized"
For a SAS, decode the query string and inspect st, se, sp, sr, sip:
# Given a SAS like ?sv=...&st=...&se=...&sp=racwl&sr=c&sig=...
echo "?sv=2024-11-04&st=2026-07-12T00:00Z&se=2026-07-11T00:00Z&sp=r&sr=c&sig=xxxx" \
| tr '&' '\n'
Resolution
Use the correct current key. Regenerate the connection string so it carries the live key rather than a stale one:
az storage account show-connection-string \
--name mystorageacct --resource-group data-rg -o tsv
Prefer Entra ID auth over keys. For CLI and azcopy, authenticate as an identity that holds Storage Blob Data Contributor:
az storage blob upload \
--account-name mystorageacct --auth-mode login \
--container-name uploads --name report.csv --file ./report.csv
If the identity lacks the data role, grant it at the account (or container) scope:
az role assignment create \
--assignee <objectId> \
--role "Storage Blob Data Contributor" \
--scope "$(az storage account show -n mystorageacct -g data-rg --query id -o tsv)"
Fix clock skew. Enable NTP so x-ms-date matches the server:
sudo timedatectl set-ntp true
Mint a fresh, correctly-scoped SAS. Match --permissions, resource type, and a valid expiry window:
az storage container generate-sas \
--account-name mystorageacct --name uploads \
--permissions racwl --expiry 2026-07-13T00:00Z \
--auth-mode login --as-user -o tsv
If shared key is disabled by policy, do not re-enable it to “make it work” — migrate the caller to Entra ID. Re-enabling shared key is only appropriate when your security baseline permits it.
Hardening access
- Contributor is not a data role. Being Owner/Contributor on the account lets you manage it but does not grant blob/queue/table data access; you still need a
Storage ... Datarole for--auth-mode login. - Connection strings hide stale keys. After a key rotation, every stored connection string and Kubernetes secret carrying the old key breaks at once — rotate them together.
- SAS expiry is UTC. A token that “should” be valid can read as expired if your local time zone or a skewed clock shifts the comparison; always reason in UTC.
ServerFailedToAuthenticateRequestalso appears from front-door/proxy layers that strip or rewrite theAuthorizationheader — rule out an intermediary before blaming the key.
Related identity errors
- AuthorizationPermissionMismatch — the data-plane RBAC counterpart when Entra auth succeeds but the role is missing.
- ExpiredAuthenticationToken — the control-plane token expiry equivalent for ARM calls.
- KeyVault Forbidden — the same “authenticated but not authorized” pattern on Key Vault.
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.