hashicorp/terraform · error

failed to retrieve lock info

Error message

failed to retrieve lock info: %s

What it means

Returned by RemoteClient.Unlock when c.getLockInfo() fails. Wraps either error 158 (empty terraformlockid metadata) or any failure from the underlying GetProperties call (network, RBAC, blob deleted). Returned as a statemgr.LockError so terraform surfaces it appropriately during `terraform force-unlock` or automatic unlock.

Solutions

  1. Break the lease manually via `az storage blob lease break` to bypass Terraform's metadata-based unlock.
  2. Verify the identity can read blob metadata (Storage Blob Data Reader minimum).
  3. If the blob was deleted, no unlock is needed — recreate the workspace state.
  4. Retry `terraform force-unlock` after fixing permissions/network.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: confirm the identity can read blob metadata before attempting unlock.
func canReadBlobMetadata(ctx context.Context, acct, container, blob string) error {
    cmd := exec.CommandContext(ctx, "az", "storage", "blob", "show",
        "--account-name", acct, "-c", container, "-n", blob, "--query", "metadata", "-o", "json")
    if _, err := cmd.Output(); err != nil { return fmt.Errorf("cannot read blob metadata: %w", err) }
    return nil
}

Try / catch

// On Unlock failure, fall back to a manual lease break and report.
if err := client.Unlock(id); err != nil {
    var le *statemgr.LockError
    if errors.As(err, &le) {
        log.Printf("unlock failed (%v); break lease manually: az storage blob lease break --account-name %s -c %s -b %s",
            le.Err, acct, container, blob)
    }
}

Prevention

When it happens

Trigger: (a) Same as 158 (metadata empty/missing). (b) GetProperties failed: network, identity lost Read on the blob, account throttled. (c) Blob was deleted before the unlock call.

Common situations: Permissions revoked mid-run; state blob force-deleted while a lock is held; flaky network during force-unlock; manual lease break left the metadata inconsistent.

Related errors


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

Appendix: 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 d32a084675)