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

  1. Retry the unlock — transient data-plane errors often clear on the next attempt
  2. If it persists, break the lease: az storage blob lease break --account-name <account> -c <container> -b <key>
  3. Confirm the credential has 'Storage Blob Data Contributor' (write metadata) permission
  4. 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

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


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/93085719b69a7005. Report an issue: GitHub.