hashicorp/terraform · error · statemgr.LockError
failed to delete lock info from metadata: %s
Error message
failed to delete lock info from metadata: %s
What it means
Raised in RemoteClient.Unlock (client.go:288-290). After confirming the lock belongs to the caller, Unlock calls writeLockInfo(nil) which issues a SetMetaData data-plane call to clear the 'terraformlockid' metadata under the lease; if that call fails, this error wraps it in a LockError and the lease is NOT released.
Source
Thrown at internal/backend/remote-state/azure/client.go:289
func (c *RemoteClient) Unlock(id string) error {
lockErr := &statemgr.LockError{}
lockInfo, err := c.getLockInfo()
if err != nil {
lockErr.Err = fmt.Errorf("failed to retrieve lock info: %s", err)
return lockErr
}
lockErr.Info = lockInfo
if lockInfo.ID != id {
lockErr.Err = fmt.Errorf("lock id %q does not match existing lock", id)
return lockErr
}
c.leaseID = lockInfo.ID
if err := c.writeLockInfo(nil); err != nil {
lockErr.Err = fmt.Errorf("failed to delete lock info from metadata: %s", err)
return lockErr
}
ctx := newCtx()
_, err = c.giovanniBlobClient.ReleaseLease(ctx, c.containerName, c.keyName, blobs.ReleaseLeaseInput{LeaseID: id})
if err != nil {
lockErr.Err = err
return lockErr
}
c.leaseID = ""
return nil
}
View on GitHub (pinned to c9def3e214)
Solutions
- Retry the unlock — transient data-plane errors often clear on the next attempt
- If it persists, break the lease: az storage blob lease break --account-name <account> -c <container> -b <key>
- Confirm the credential has 'Storage Blob Data Contributor' (write metadata) permission
- Re-run 'terraform init' then the command
Example fix
# retry; if the metadata clear keeps failing, break the lease az storage blob lease break \ --account-name mystage --auth-mode login \ -c tfstate -b "prod.terraform.tfstate" terraform init terraform apply
Defensive patterns
Strategy: retry
Validate before calling
# Confirm data-plane write (metadata) permission before relying on clean unlock az role assignment list --assignee "$ARM_CLIENT_ID" --scope "$ACCOUNT_ID" --query "[].roleDefinitionName" -o tsv | grep -iE 'Storage Blob Data (Contributor|Owner)' \ && echo "OK: metadata write permission" || echo "WARN: may fail to clear lock metadata (158)"
Try / catch
# Retry the metadata-clearing unlock; break lease if it keeps failing
unlock_with_retry() {
for attempt in 1 2 3; do
terraform force-unlock -force "$1" 2>/dev/null && return 0
grep -q "failed to delete lock info from metadata" && sleep $((attempt*5)) || return 1
done
az storage blob lease break --account-name "$ARM_STORAGE_ACCOUNT_NAME" -c "$ARM_CONTAINER_NAME" -n "$ARM_KEY"
} Prevention
- Grant 'Storage Blob Data Contributor' so metadata writes succeed
- Retry unlock on transient SetMetaData failures before escalating
- Break the lease at the Azure layer if metadata clearing persistently fails
When it happens
Trigger: Produced at client.go:288-290 when c.writeLockInfo(nil) returns an error during Unlock — the SetMetaData data-plane call failed (network, auth, or lease-ID mismatch on the metadata write).
Common situations: Transient data-plane error during metadata write; the lease expired/break between confirm and metadata clear; data-plane permission lacks 'write' for metadata; a concurrent operation modified the blob.
Related errors
- failed to retrieve lock info: %s
- blob metadata %q was empty
- lock id %q does not match existing lock
- failed to lock azure state: %s
- Error unlocking Azure state. Lock ID: %s Error: %s You may
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/93085719b69a7005.
Report an issue: GitHub.