# Azure VM Using Unmanaged Disks

> Unmanaged disks (page blobs the customer parks in storage accounts) were retired on 2026-03-31, and VMs still using them can no longer be started. RC-1307 fires when the discoverer reports managed_disk_enabled false, derived from the absence of storageProfile.osDisk.managedDisk, which makes this migration mandatory rather than advisory.

Source: https://zop.dev/integrations/azure/recommendations/azure-vm-using-unmanaged-disks
Updated: 2026-08-19

---

## A hard deadline, not a modernisation nudge

Most compliance findings describe best practice; a few describe a cliff. Unmanaged disks were
retired on 2026-03-31: a VM still built on them cannot be started once stopped, which turns
"legacy storage pattern" into "production machine that will not survive its next reboot
cycle". Anything this rule surfaces belongs at the top of the queue for that reason alone:
the risk isn't degraded redundancy, it's a VM that is one deallocation away from being
unbootable.

## Telling VHDs from managed disks in ARM

Managed and unmanaged disks are distinguishable from a single property: a managed-disk VM
carries `storageProfile.osDisk.managedDisk` (a resource reference), while an unmanaged VM
instead names a raw `vhd.uri` pointing into a storage account. The discoverer folds that
presence check into a `managed_disk_enabled` metadata flag, emitted in both polarities. The
rule fires only on the explicit `"false"` and abstains when the key was never stamped. An
older version watched a `managed_disks` tag no producer wrote, so it never fired on anything.

## What the old model actually cost you

Unmanaged disks made you the storage engineer: capacity planning for storage-account IOPS
ceilings, spreading VHDs across accounts to dodge throttling, and no per-disk RBAC, no disk
snapshots as first-class resources, no availability-set fault isolation between disks in one
account. Managed disks absorbed all of that into the platform, which is why the retirement is
one-way.

## Find remaining unmanaged-disk VMs

```bash
az vm list \
  --query "[?storageProfile.osDisk.vhd!=null].{name:name, rg:resourceGroup, vhd:storageProfile.osDisk.vhd.uri}" \
  -o table
```

Non-empty output is the exact population RC-1307 reports.

## The migration path and the cleanup after

Migration is built in: stop-deallocate the VM, run `az vm convert -g <rg> -n <vm>`, and the
platform converts every attached VHD to managed disks before restart. Plan the window because
the deallocate is unavoidable. Afterwards, delete the orphaned VHD blobs, because conversion
copies rather than moves and the source storage account keeps billing until emptied. Detection is
Reader-only; ZopNight performs no conversions.
