The goal
You are decommissioning a Recovery Services vault, or deleting a resource group that contains one, and the delete fails with:
- Vault cannot be deleted as there are existing resources within the vault. Please ensure there are no backup items, protected servers, or backup management servers associated with this vault...
- Recovery Services vault cannot be deleted as there are backup items in soft deleted state in the vault...
A vault refuses deletion while it still has protected items, registered servers or storage accounts, replicated items or private endpoint connections. This runbook finds each one and removes it in the right order.
Caution
Every step below permanently ends protection for something. Before you start, confirm in writing that no workload, audit or legal hold needs the recovery points in this vault. Deleted backup data goes into soft delete for the vault's soft-delete retention period. After that it is gone.
What changed: soft delete is always on
Older runbooks say "disable soft delete, undelete the items, delete them again, then delete the vault". That no longer works for Recovery Services vaults. Under Azure Backup's secure-by-default rollout:
- Soft delete can't be disabled from the portal, CLI, PowerShell or REST.
- Deleting a backup item always moves it into the soft-deleted state.
- A vault that is empty, or holds only soft-deleted items and containers, can be deleted. The vault itself moves into a soft-deleted state and is purged when the retention period ends.
- Soft-delete retention is 14 days by default and can be set up to 180 days. Retention beyond 14 days is charged at normal backup rates.
So you don't wait 14 days any more. You clear the active dependencies and then delete. Older CLI and PowerShell versions behave differently. Use Azure CLI 2.75.0 or later and Az.RecoveryServices 7.5.0 or later, and check the current Azure Backup documentation if your region's behaviour doesn't match.
Step 0: set variables and check blockers outside the vault
RG=rg-backup-legacy
VAULT=rsv-legacy-weu
VAULT_ID=$(az backup vault show -g $RG -n $VAULT --query id -o tsv)
# Resource locks on the vault or resource group block deletion
az lock list -g $RG -o table
# Soft-delete state, retention and other security settings
az backup vault backup-properties show -g $RG -n $VAULT -o json
Two more things can block you before you even reach the dependencies:
- Multi-user authorization (MUA): if a Resource Guard protects the vault, protected operations need approval from whoever owns the guard, often through a PIM role on the Resource Guard. Request it first.
- Immutable vault: recovery points can't be deleted before they expire. If immutability is locked, it can't be turned off. Find out when the last recovery point expires before you promise a decommission date.
Step 1: inventory every dependency
# Backup items per management type
for T in AzureIaasVM AzureStorage AzureWorkload MAB; do
echo "== $T"
az backup item list -g $RG -v $VAULT --backup-management-type $T \
--query "[].{item:properties.friendlyName, container:properties.containerName, state:properties.protectionState, softDeleted:properties.isScheduledForDeferredDelete}" \
-o table
done
# Registered containers (VMs with SQL, storage accounts, MARS servers)
for T in AzureIaasVM AzureStorage AzureWorkload MAB; do
echo "== $T"
az backup container list -g $RG -v $VAULT --backup-management-type $T \
--query "[].{name:name, friendly:properties.friendlyName, status:properties.registrationStatus}" -o table
done
# Private endpoint connections on the vault
az resource show --ids $VAULT_ID --query "properties.privateEndpointConnections[].{name:name, state:properties.privateLinkServiceConnectionState.status}" -o table
Also check two places in the portal that the CLI loop doesn't cover well: Backup Infrastructure > Backup Management Servers (MABS/DPM) and Site Recovery > Replicated items. The vault Overview > Delete pane shows the same list with links to each blade, and it is a good final check.
| What the inventory shows | Why it blocks deletion | How to clear it |
|---|---|---|
Item with state Protected or ProtectionStopped | Active backup data | Stop protection and delete data (Step 2) |
Item with softDeleted: true | Allowed under secure-by-default | Nothing. The vault soft-deletes with it |
| SQL/SAP HANA auto-protection on a VM | New databases get protected again | Disable auto-protection first |
AzureStorage container | Storage account registered for Azure Files backup | Unregister the storage account |
MAB container | MARS agent server registered | Delete the protected server |
| Backup management server | MABS/DPM registered | Delete online data, then unregister |
| Replicated item | Site Recovery protection | Disable replication |
| Private endpoint connection | Vault networking dependency | Delete the private endpoint |
Step 2: stop protection and delete backup data
For Azure VMs, the CLI handles it directly:
az backup item list -g $RG -v $VAULT --backup-management-type AzureIaasVM \
--query "[?properties.isScheduledForDeferredDelete!=\`true\`].[properties.containerName, name]" -o tsv |
while read CONTAINER ITEM; do
az backup protection disable -g $RG -v $VAULT \
--container-name "$CONTAINER" --item-name "$ITEM" \
--backup-management-type AzureIaasVM --delete-backup-data true --yes
done
For Azure Files and SQL in Azure VM, PowerShell covers every workload type. Disable SQL auto-protection on each instance first, or new databases will be protected again:
$vault = Get-AzRecoveryServicesVault -ResourceGroupName 'rg-backup-legacy' -Name 'rsv-legacy-weu'
$targets = @(
@{ Mgmt = 'AzureStorage'; Workload = 'AzureFiles' },
@{ Mgmt = 'AzureWorkload'; Workload = 'MSSQL' }
)
foreach ($t in $targets) {
Get-AzRecoveryServicesBackupItem -BackupManagementType $t.Mgmt -WorkloadType $t.Workload -VaultId $vault.ID |
Where-Object { -not $_.IsScheduledForDeferredDelete } |
ForEach-Object {
Disable-AzRecoveryServicesBackupProtection -Item $_ -RemoveRecoveryPoints -VaultId $vault.ID -Force
}
}
Parameter names vary between Az.RecoveryServices versions (IsScheduledForDeferredDelete in particular). Run the pipeline without the Disable- line first and check the output.
Warning
Stopping protection does not touch the VM, file share or database. It only removes the backup. Double-check that you are in the right vault, because the same VM name can be protected in a vault in another subscription.
Step 3: unregister storage accounts and servers
# Storage accounts used for Azure Files backup (after their file share items are deleted)
az backup container list -g $RG -v $VAULT --backup-management-type AzureStorage --query "[].name" -o tsv |
while read C; do
az backup container unregister -g $RG -v $VAULT --container-name "$C" \
--backup-management-type AzureStorage --yes
done
- MARS servers: in Backup Infrastructure > Protected Servers > Azure Backup Agent, delete each server and accept the consent box. This deletes its backup data too. Uninstall the agent on the machine afterwards so failed jobs stop raising alerts.
- MABS/DPM: in the MABS/DPM console, stop protection with Delete online storage (it asks for a security PIN from the vault's Properties page, valid for five minutes), then delete the server under Backup Management Servers.
- SQL/SAP HANA VMs: once their items are deleted, unregister the
AzureWorkloadcontainer with the sameunregistercommand and--backup-management-type AzureWorkload.
Step 4: Site Recovery and private endpoints
- In Site Recovery > Replicated items, select Disable replication for each item. Then remove the leftover fabric pieces (replication policies, network mappings, configuration or process servers for VMware/physical).
- Delete any private endpoint for the vault:
az network private-endpoint list --query "[?privateLinkServiceConnections[0].privateLinkServiceId=='$VAULT_ID'].{name:name, rg:resourceGroup}" -o table
az network private-endpoint delete -g <pe-resource-group> -n <pe-name>
Step 5: delete the vault
az backup vault delete -g $RG -n $VAULT --yes
If it still fails, re-run the Step 1 inventory. The error message usually names the container that is left. Only if the inventory is empty and the delete still fails, follow Microsoft's documented fallback of deleting the vault through Azure Resource Manager directly, and open a support case if that fails too.
Tip
A soft-deleted vault can be recovered within its retention period. You can create a new vault with the same name in the same resource group straight away, which is useful when IaC redeploys the same name.
Prevent it next time
- Decommission backup in the same change as the workload. When a VM, file share or SQL instance is retired, stop protection in that change. Orphaned items keep their last recovery point indefinitely and keep costing money.
- Keep one vault per purpose. A vault shared by VMs, MARS servers and Site Recovery takes three teams to delete.
- Tag vaults with owner and decommission date, and review vaults with zero protected items monthly using Azure Resource Graph or the Business Continuity Center.
- Write MUA and immutability into the decommission plan. Locked immutability and Resource Guards are deliberate brakes. Know who holds the keys before the deadline.
- Use current tools. Old CLI and PowerShell versions follow older soft-delete rules and give misleading errors.