Home / Azure

AzureTroubleshootingIntermediate

Azure VM won't start or resize: AllocationFailed, ZonalAllocationFailed and SkuNotAvailable

A VM start, resize or scale-out fails with an allocation, SKU or quota error. Tell the three apart, get the VM running again and reserve capacity for the machines that can't wait.

Deepak Bhardwaj8 min read

Applies toAzure Virtual Machines and Virtual Machine Scale Sets (all regions); Azure CLI 2.x

The symptom: a VM that was deallocated overnight won't start in the morning, a resize fails, or a scale set won't add instances. The portal shows a red banner and the error code is one of AllocationFailed, ZonalAllocationFailed, OverconstrainedAllocationRequest, SkuNotAvailable or OperationNotAllowed with a quota message. These look similar but have different fixes. An allocation failure means Azure couldn't find hardware for that size in that place right now. A SKU or quota error means your subscription isn't allowed to have it at all.

Step 1: get the exact error

The portal often truncates the message. Pull it from the Activity Log:

az monitor activity-log list -g rg-prod --offset 6h --status Failed \
  --query "[?contains(operationName.value, 'Microsoft.Compute')].{time:eventTimestamp, op:operationName.value, resource:resourceId, msg:properties.statusMessage}" \
  -o json

The statusMessage field holds the JSON error with the code and the text. If the operation came from a pipeline, look at the deployment instead:

az deployment operation group list -g rg-prod -n <deployment-name> \
  --query "[?properties.provisioningState=='Failed'].properties.statusMessage" -o json

Step 2: match the code to the cause

Error code What it means First fix
AllocationFailed No capacity for this size on the cluster or region the request was pinned to Retry later, try a different size, or deallocate fully and start
ZonalAllocationFailed No capacity for this size in the requested availability zone Try a different size in the same zone, or retry later
OverconstrainedAllocationRequest / OverconstrainedZonalAllocationRequest The combination of constraints (size, zone, proximity placement group, accelerated networking, ultra disk, availability set) can't be met Remove or relax one constraint
SkuNotAvailable The size isn't offered in this region or zone for your subscription Choose an available size or request access
OperationNotAllowed with "exceeding approved ... quota" Your vCPU quota for the family or region is used up Free cores or raise the quota
QuotaExceeded (scale sets, deployments) Same as above, different surface Same as above

Names and messages vary a little by API version and portal; the code in the JSON is what to match on.

Step 3: fix a SkuNotAvailable error

Check whether the size is offered where you asked for it, including per-zone restrictions:

az vm list-skus --location westeurope --size Standard_D8s_v5 --all -o table

The Restrictions column shows NotAvailableForSubscription if the size is blocked for you, and lists the affected zones if only some zones are restricted. --all is needed; without it the CLI hides restricted SKUs and you see nothing, which is easy to misread as "size doesn't exist".

To list zone-capable sizes in the region with no restrictions for your subscription:

az vm list-skus --location westeurope --zone --resource-type virtualMachines \
  --query "[?locationInfo[0].zones && !restrictions].name" -o tsv | sort

If the size you need is restricted, open a support request for the region and SKU (quota/region access type). Meanwhile, pick the nearest equivalent size from the unrestricted list.

Step 4: fix a quota error

Look at regional and per-family vCPU usage:

az vm list-usage --location westeurope \
  --query "[?currentValue > \`0\`].{name:localName, used:currentValue, limit:limit}" -o table

Two limits apply at once: Total Regional vCPUs and the family limit (for example Standard DSv5 Family vCPUs). Either one blocks the request. Free cores by deleting unused VMs (deallocated VMs don't count against vCPU quota), or request an increase from Quotas in the portal. Increases for common families are often approved automatically; larger ones go to review, so don't make a quota request your incident plan.

Step 5: fix an allocation failure

Allocation failures are capacity problems, not configuration problems. Your options, roughly in order of speed:

Start or resize from a fully deallocated state

A running or stopped (not deallocated) VM is pinned to its current hardware cluster. A resize can only pick sizes that cluster supports. List them:

az vm list-vm-resize-options -g rg-prod -n vm-app-01 --query "[].name" -o tsv

If your target size isn't in that list, deallocate first. A deallocated VM can be placed on any cluster in the region (or zone) that has the size:

az vm deallocate -g rg-prod -n vm-app-01
az vm resize -g rg-prod -n vm-app-01 --size Standard_D8s_v5
az vm start -g rg-prod -n vm-app-01

Warning

Deallocating releases the dynamic public IP and wipes the temporary disk (D: on Windows, /mnt or /mnt/resource on Linux). It also means the VM might not get capacity back if the region is tight. Use a static public IP and don't keep anything on the temp disk.

Availability sets: move the whole set

All VMs in an availability set must sit on the same cluster. If one VM can't be resized or started, deallocate every VM in the set, then resize and start them. Starting them one by one is fine; the first start picks a cluster that supports the size.

for vm in $(az vm list -g rg-prod --query "[?availabilitySet && contains(availabilitySet.id, 'avset-app')].name" -o tsv); do
  az vm deallocate -g rg-prod -n "$vm" --no-wait
done

This is downtime for the whole tier. Plan it.

Proximity placement groups

A PPG pins VMs close together, which narrows where they can land. Start the VM with the most specialised size first (the one with the least capacity), then the rest. If it still fails, deallocate all VMs in the PPG and start them again in that order.

Change size or zone

If the same size keeps failing, a sibling size (a different version or the AMD/Intel variant of the same family) is often available. A zonal VM can't be moved to another zone by a simple start; you would rebuild it from snapshots of its disks in the other zone. For scale sets, adding zones to the set or allowing more than one size (where your scale set type supports mixed sizes) gives the platform more room.

Retry with back-off

Capacity frees up as other customers deallocate. A retry loop is a legitimate fix for a VM that isn't urgent:

for i in 1 2 3 4 5 6; do
  az vm start -g rg-prod -n vm-app-01 && break
  echo "Attempt $i failed, waiting 10 minutes"; sleep 600
done

Step 6: check whether it's wider than you

If many VMs or several sizes fail in the same region at once, look at Service Health for capacity advisories and at the Resource Health of the VM:

# Needs the resource-graph extension (the CLI offers to install it)
az graph query -q "
healthresources
| where type =~ 'microsoft.resourcehealth/availabilitystatuses'
| where id contains '/virtualMachines/'
| extend state = tostring(properties.availabilityState), summary = tostring(properties.summary)
| where state != 'Available'
| project id, state, summary" -o table

Prevent it next time

  • Don't deallocate VMs you can't afford to lose capacity for. Out-of-hours shutdown saves money, but it gives up the allocation. Leave critical VMs running or reserve capacity for them.
  • Use on-demand capacity reservations for VMs that must start during an incident or a DR failover. You pay for the reserved capacity whether or not a VM uses it, so reserve only what matters:
az capacity reservation group create -g rg-prod -n crg-weu --zones 1
az capacity reservation create -g rg-prod --capacity-reservation-group crg-weu \
  -n cr-d8sv5 --sku Standard_D8s_v5 --capacity 2 --zone 1

# Associate an existing VM (the VM must be deallocated)
az vm update -g rg-prod -n vm-app-01 \
  --capacity-reservation-group /subscriptions/<sub-id>/resourceGroups/rg-prod/providers/Microsoft.Compute/capacityReservationGroups/crg-weu
  • Keep quota headroom. Alert when regional vCPU usage passes about 80% of the limit and raise the quota before a scale-out or DR test needs it.
  • Don't over-constrain. Only use PPGs, specific zones and niche sizes where the workload needs them. Every constraint shrinks the pool of hardware that can take your VM.
  • Have a fallback size written into the runbook for each critical VM, already checked with az vm list-skus in the target region and zone.

Tip

Reservations (the billing discount) and Savings Plans do not guarantee capacity. Only on-demand capacity reservations do. Check the current pricing and limits before you rely on them in a DR plan.