Azure Error Guide: 'ScopeLocked' — Remove or Work Around the Resource Lock
Fix Azure 'ScopeLocked' delete failures: find the CanNotDelete or ReadOnly lock, identify its scope, remove it safely with the right RBAC role, and prevent locks from blocking deployments.
- #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.
Overview
Azure Resource Manager returns ScopeLocked when you try to delete or modify a resource that is protected by a management lock — or that inherits one from its resource group or subscription:
Code: ScopeLocked
Message: The scope '/subscriptions/1111.../resourceGroups/prod-rg/providers/Microsoft.Storage/storageAccounts/prodsa'
cannot perform delete operation because following scope(s) are locked:
'/subscriptions/1111.../resourceGroups/prod-rg'. Please remove the lock and try again.
Azure has two lock levels. A CanNotDelete lock lets you read and modify a resource but blocks deletion; a ReadOnly lock blocks any modification as well as deletion (surfacing as ScopeLocked on writes, sometimes reported with the operation as read-only). Locks are inherited downward: a lock on a subscription or resource group applies to every resource inside it. That inheritance is why the scope named in the “locked” list is often a parent of the resource you were actually trying to change — the resource itself has no lock, but its resource group does.
Symptoms
- A
deleteor write operation fails withScopeLockedand the message names a scope (often a resource group or subscription, not the resource itself). - Terraform
destroyorapplyfails on a resource that has no lock of its own, blocked by an inherited lock. az group deleterefuses to remove a resource group that contains locked resources.- The Azure Portal greys out the Delete button with a “resource is locked” note.
- A CI pipeline that recreates infrastructure suddenly fails after a lock was added manually for compliance.
- Removing the lock fails too — with
AuthorizationFailed— because the identity lacksMicrosoft.Authorization/locks/*permissions.
Common Root Causes
- A CanNotDelete lock placed on a production resource or resource group to prevent accidental deletion.
- An inherited lock at the resource group or subscription scope applying to a child you are trying to change.
- A ReadOnly lock blocking updates as well as deletes (this even prevents some data-plane operations, like listing storage keys).
- Locks applied by Azure Policy or a landing zone as a guardrail, recreated automatically if you delete them manually.
- Insufficient permissions to manage locks — the deploying identity can change resources but not locks, so it can neither delete nor unlock.
- Leftover locks from a blueprint or deny assignment that behave like locks and block deletion at a managed scope.
Diagnostic Workflow
List locks at the resource, resource group, and subscription scope — ScopeLocked names the locked scope, but check all levels because of inheritance:
# Locks visible at/under the resource group (includes inherited)
az lock list -g prod-rg -o table
# Locks scoped directly to a specific resource
az lock list -g prod-rg --resource prodsa \
--resource-type Microsoft.Storage/storageAccounts --namespace Microsoft.Storage -o table
# Subscription-level locks
az lock list -o table
Get the full details (level and id) of the lock named in the error:
az lock show --name <lockName> -g prod-rg -o json
Confirm your identity can manage locks — you need a role granting Microsoft.Authorization/locks/*, which is held by Owner and User Access Administrator (a custom role may omit it):
az role assignment list --assignee <appId> --scope /subscriptions/<subId>/resourceGroups/prod-rg -o table
Check whether the lock is recreated by policy or a landing zone (if it reappears after deletion, it is managed):
az policy assignment list --resource-group prod-rg -o table
Example Root Cause Analysis
An engineer ran terraform destroy to tear down an ephemeral test stack and it failed on a single storage account:
Error: deleting Storage Account "prodsa": Code="ScopeLocked"
Message="... cannot perform delete operation because following scope(s) are locked:
'/subscriptions/1111.../resourceGroups/prod-rg'."
The storage account itself had no lock, so the engineer first suspected Terraform state drift. Listing locks revealed the truth:
az lock list -g prod-rg -o table
# Name Level ResourceGroup
# ------------- ------------- -------------
# prevent-delete CanNotDelete prod-rg
A CanNotDelete lock had been applied to the entire resource group weeks earlier during a compliance review, and it was inherited by every resource inside — including the test stack that had been deployed into the wrong (production) resource group. Two problems surfaced: the lock was doing its job, and the ephemeral stack should never have been in prod-rg. The immediate unblock, after confirming the resource was genuinely disposable, was to remove the lock for the operation and reapply it:
az lock delete --name prevent-delete -g prod-rg
terraform destroy
az lock create --name prevent-delete --lock-type CanNotDelete -g prod-rg \
--notes "Prevent accidental deletion of production resource group"
The durable fix was moving ephemeral workloads to their own unlocked resource group so the production lock never had to be lifted.
Prevention Best Practices
- Isolate lockable and ephemeral resources. Keep short-lived / CI-managed resources in resource groups that are never locked, so tear-downs don’t fight production locks.
- Prefer CanNotDelete over ReadOnly unless you truly need to freeze all changes — ReadOnly blocks legitimate updates and some data-plane calls, causing surprising failures.
- Automate lock lifecycle. If a pipeline must recreate a locked resource, script “remove lock → change → reapply lock” as an explicit, audited step rather than lifting locks by hand.
- Grant lock-management rights deliberately. Identities that need to manage locks require Owner or User Access Administrator at the right scope; don’t hand these out broadly.
- Document why each lock exists. Use the
--notesfield so the next engineer knows whether the lock is safe to remove or is a compliance requirement. - Watch for policy-managed locks. If a lock reappears after deletion, it’s enforced by policy or a landing zone — change it at the source, not on the resource.
Quick Command Reference
# List locks (includes inherited) at a resource group
az lock list -g prod-rg -o table
# List subscription-level locks
az lock list -o table
# Show a specific lock's level and id
az lock show --name prevent-delete -g prod-rg -o json
# Delete a lock
az lock delete --name prevent-delete -g prod-rg
# Recreate a CanNotDelete lock with notes
az lock create --name prevent-delete --lock-type CanNotDelete -g prod-rg \
--notes "Compliance: prevent accidental deletion"
# Delete a lock scoped to a single resource
az lock delete --name <lockName> -g prod-rg --resource prodsa \
--resource-type Microsoft.Storage/storageAccounts --namespace Microsoft.Storage
Conclusion
ScopeLocked means a management lock — usually inherited from a parent resource group or subscription — is doing exactly what it was created to do: block a delete or write. Diagnose it by listing locks at every scope (the locked scope in the message is frequently a parent, not your target resource), confirm you have lock-management rights, and remove or reapply the lock as a deliberate, audited action. The lasting fix is structural: keep ephemeral and lock-protected resources in separate resource groups so routine tear-downs never collide with a production lock.
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.