Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
Azure with AI By James Joyner IV · · 8 min read Last reviewed Jul 2026

Azure Error Guide: 'PropertyChangeNotAllowed' — Update Immutable Resource Fields

Quick answer

Fix Azure 'PropertyChangeNotAllowed' errors: identify the immutable property (VM zone, disk, subnet), stop trying to update it in place, and recreate or migrate the resource the supported way.

  • #azure
  • #cloud
  • #troubleshooting
  • #errors
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Overview

Azure Resource Manager returns PropertyChangeNotAllowed when a deployment or update tries to change a property that is immutable after creation. The resource exists and you are authorized to update it, but the specific field you changed cannot be modified in place — it can only be set when the resource is first created.

Code: PropertyChangeNotAllowed
Message: Changing property 'availabilitySet.properties.virtualMachines' is not allowed.

Other common literal variants of the same error code:

Code: PropertyChangeNotAllowed
Message: Changing property 'osDisk.managedDisk.storageAccountType' is not allowed while the VM is running.

Code: PropertyChangeNotAllowed
Message: Property 'subnet.properties.addressPrefix' cannot be changed because the subnet
is in use by one or more resources.

Code: PropertyChangeNotAllowed
Message: Changing property 'zones' is not allowed.

The message always names the exact property path that ARM refused to change — that path is the whole diagnosis.

Symptoms

  • A Bicep/ARM/Terraform apply or az ... update fails with PropertyChangeNotAllowed, naming a specific property path.
  • The rest of the template deploys fine; only the change to one field is rejected.
  • Terraform may instead show a plan that forces replacement — accepting it deletes and recreates the resource, which is the same immutability surfacing differently.
  • The change works after you stop/deallocate the resource for some properties (e.g. disk SKU on a running VM) but is impossible for others (e.g. availability zone).

Common Root Causes

  • Availability zone / zones on a VM or resourcezones is fixed at creation. You cannot move a running VM to another zone by editing the property.
  • Availability set membership — moving an existing VM into or out of an availability set is not an in-place update.
  • OS/data disk SKU while runningstorageAccountType (e.g. Standard_LRS → Premium_LRS) often requires the VM to be deallocated first.
  • VM size across incompatible families — some size changes require deallocation; a few property combinations are outright immutable.
  • Subnet address prefix in use — you cannot shrink/change a subnet’s addressPrefix while NICs or delegated services occupy it.
  • Storage account replication or region-affecting properties, and Key Vault properties like enablePurgeProtection (once enabled, it cannot be disabled).
  • Resource name / location — changing name or region is never an update; it is a new resource.
  • Encryption / identity fields set at creation on certain resources (e.g. some encryption blocks, subnet service delegations in use).

Diagnostic Workflow

Read the property path in the error — it is the exact field to stop changing. Then compare your desired template against the deployed resource to confirm which field drifted:

# Dump the current live resource as JSON
az resource show \
  --ids <resource-id> \
  -o json > current.json

For a VM zone/disk case, inspect the immutable fields directly:

az vm show -g <rg> -n <vm> \
  --query "{zones:zones, size:hardwareProfile.vmSize, osDiskSku:storageProfile.osDisk.managedDisk.storageAccountType}" \
  -o json

Run a what-if to see exactly which property ARM thinks is changing before you deploy:

az deployment group what-if \
  --resource-group <rg> \
  --template-file main.bicep \
  --parameters @params.json

For a running-VM disk SKU change, confirm power state (some changes need deallocation, not just stop):

az vm get-instance-view -g <rg> -n <vm> \
  --query "instanceView.statuses[?starts_with(code,'PowerState')].displayStatus" -o tsv

For a subnet prefix change, list what still occupies the subnet:

az network vnet subnet show -g <rg> --vnet-name <vnet> -n <subnet> \
  --query "{prefix:addressPrefix, ipConfigs:ipConfigurations[].id}" -o json

Example Root Cause Analysis

A team wants to make a production VM zone-redundant by editing their Bicep to set zones: ['2'] on an existing zone-1 VM. The deployment fails:

Code: PropertyChangeNotAllowed
Message: Changing property 'zones' is not allowed.

az vm show confirms the live VM has zones: ["1"]. Availability zone placement is chosen at VM creation and is immutable — there is no in-place move. Editing the property will always be rejected, and forcing it through Terraform would destroy and recreate the VM.

The supported path is to recreate in the target zone, not to update:

  1. Snapshot the OS (and data) disks:
    az snapshot create -g <rg> -n vm-osdisk-snap \
      --source $(az vm show -g <rg> -n <vm> --query storageProfile.osDisk.managedDisk.id -o tsv)
  2. Create a managed disk from the snapshot in the target zone:
    az disk create -g <rg> -n vm-osdisk-z2 --source vm-osdisk-snap --zone 2
  3. Create a new VM in zone 2 attached to that disk, cut over, and retire the old VM.

The immutable property is respected by building a new resource rather than fighting the update.

Prevention Best Practices

  • Treat zone, availability set, name, and location as create-time decisions. Design these correctly up front; changing them later always means recreation and a cutover.
  • Read the property path first. The error names the exact immutable field — check the docs for whether it needs deallocation (fixable) or full recreation (immutable).
  • Always run what-if (ARM/Bicep) or review the Terraform plan. A plan that shows “forces replacement” is your warning that a property is immutable before you destroy production.
  • Deallocate for the fixable cases. Disk SKU and some size changes succeed once the VM is deallocated — stop-and-deallocate, apply, restart.
  • Model immutable properties in modules. Encode zone/availability-set choices as required inputs so a later edit is caught in review, not at deploy time.
  • Know the one-way switches. Key Vault purge protection and soft delete, once enabled, cannot be disabled — enabling them is a deliberate, permanent choice.

Quick Command Reference

# The current live definition
az resource show --ids <resource-id> -o json

# VM immutable fields at a glance
az vm show -g <rg> -n <vm> --query "{zones:zones,size:hardwareProfile.vmSize}" -o json

# See exactly what property will change before deploying
az deployment group what-if -g <rg> --template-file main.bicep --parameters @params.json

# Power state (does the change need deallocation?)
az vm get-instance-view -g <rg> -n <vm> \
  --query "instanceView.statuses[?starts_with(code,'PowerState')].displayStatus" -o tsv

# Recreate in a target zone (immutable path)
az snapshot create -g <rg> -n osdisk-snap --source <osdisk-id>
az disk create -g <rg> -n osdisk-z2 --source osdisk-snap --zone 2

Conclusion

PropertyChangeNotAllowed is Azure telling you a field is fixed for the life of the resource. The error names the exact property path, and that single detail tells you which of two situations you are in: a deallocate-and-retry case (disk SKU, some VM sizes) or a recreate-and-migrate case (availability zone, availability set, name, location). Run what-if or read the Terraform plan before applying so an immutable change never surprises you as a forced replacement of a production resource, and encode these create-time decisions as required inputs in your IaC so they are settled by design rather than discovered at deploy time.

Free download · 368-page PDF

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?

Free download · 368-page PDF

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.