hashicorp/terraform · error · statemgr.LockError

failed to retrieve lock info: %s

Error message

failed to retrieve lock info: %s

What it means

Raised in RemoteClient.Unlock (client.go:275-278). Unlock first calls getLockInfo to confirm the holder before releasing; if that fails — either a GetProperties data-plane error or the empty-metadata case (error 155) — this error wraps the cause in a LockError. The lock is not released.

Source

Thrown at internal/backend/remote-state/azure/client.go:277

		value := base64.StdEncoding.EncodeToString(info.Marshal())
		blob.MetaData[lockInfoMetaKey] = value
	}

	opts := blobs.SetMetaDataInput{
		LeaseID:  &c.leaseID,
		MetaData: blob.MetaData,
	}

	_, err = c.giovanniBlobClient.SetMetaData(ctx, c.containerName, c.keyName, opts)
	return err
}

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 {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Retry the Terraform command — transient GetProperties errors often clear
  2. If the metadata is corrupt (155), break the lease: az storage blob lease break --account-name <account> -c <container> -b <key>
  3. Verify network connectivity to the storage endpoint and that the blob still exists
  4. Re-run 'terraform init' then the command

Example fix

# retry; if it 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

# Pre-check: can we read blob properties (GetProperties) before relying on unlock
az storage blob show --account-name "$ARM_STORAGE_ACCOUNT_NAME" -c "$ARM_CONTAINER_NAME" -n "$ARM_KEY" >/dev/null 2>&1 \
  && echo "OK: GetProperties works" || echo "WARN: cannot read blob -> unlock may fail (156)"

Try / catch

# Retry unlock on transient GetProperties failure; break lease as fallback
safe_unlock() {
  for attempt in 1 2 3; do
    if terraform force-unlock -force "$1" 2>/dev/null; then return 0; fi
    sleep $((attempt*5))
  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:275-277 during 'terraform' teardown when c.getLockInfo() returns an error. Underlying cause is reported after the colon (GetProperties network failure, or 'blob metadata ... was empty').

Common situations: Transient data-plane error reading blob properties during unlock; the lock metadata is corrupt/empty (155); the blob was deleted while locked; network blip to the storage endpoint.

Related errors


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