opentofu/opentofu · error · statemgr.LockError

lock ID %q does not match existing lock ID "%s/%s"

Error message

lock ID %q does not match existing lock ID "%s/%s"

What it means

In the force-unlock path where the client has no in-process lock info (r.lockInfo == nil), the remote backend only accepts the composite lock ID "organization/workspace-name". Any other value — for example a UUID-style lock ID from the local backend — is rejected, with the expected ID echoed inside the message.

Source

Thrown at internal/backend/remote/backend_state.go:212

		// Verify the expected lock ID.
		if r.lockInfo.ID != id {
			lockErr.Err = fmt.Errorf("lock ID does not match existing lock")
			return lockErr
		}

		// Unlock the workspace.
		_, err := r.client.Workspaces.Unlock(ctx, r.workspace.ID)
		if err != nil {
			lockErr.Err = err
			return lockErr
		}

		return nil
	}

	// Verify the optional force-unlock lock ID.
	if r.organization+"/"+r.workspace.Name != id {
		lockErr.Err = fmt.Errorf(
			"lock ID %q does not match existing lock ID \"%s/%s\"",
			id,
			r.organization,
			r.workspace.Name,
		)
		return lockErr
	}

	// Force unlock the workspace.
	_, err := r.client.Workspaces.ForceUnlock(ctx, r.workspace.ID)
	if err != nil {
		lockErr.Err = err
		return lockErr
	}

	return nil
}

View on GitHub (pinned to 3561785c48)

Solutions

  1. Run force-unlock with the exact "ORG/WORKSPACE-NAME" string shown between the quotes in this error.
  2. Double-check the organization and workspace names in your backend block for typos and casing.
  3. If the CLI still rejects it, unlock via the workspace UI (Settings > Locking).

Example fix

# before: local-style UUID used against a remote workspace
tofu force-unlock 2b002e2c-91f7-4d9f-a4a3-fbe7ff205e35

# after: the composite org/workspace lock ID from the error message
tofu force-unlock "my-org/prod"
Defensive patterns

Strategy: validation

Validate before calling

// Build and verify the expected force-unlock ID before invoking it
expected := fmt.Sprintf("%s/%s", organization, workspaceName)
if unlockID != expected {
    return fmt.Errorf("expected lock ID %q, got %q — remote backend force-unlock takes ORG/WORKSPACE", expected, unlockID)
}

Prevention

When it happens

Trigger: tofu force-unlock <id> against a remote backend workspace where <id> is not the exact "ORG/WORKSPACE" string, e.g. a UUID copied from a local-backend lock error or the workspace's internal ID used instead of its name.

Common situations: Pasting a lock ID from a different backend type; using the workspace ID (ws-xxxx) instead of its name; wrong organization name or casing; trailing whitespace in the ID argument.

Related errors


AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15). Data as JSON: /api/errors/3f319eff141c2aaf. Report an issue: GitHub.