hashicorp/terraform · error
lock ID does not match existing lock ID " /
Error message
lock ID %q does not match existing lock ID "%s/%s"
What it means
Force-unlock path taken when r.lockInfo is nil (no tracked lock). Terraform requires the supplied id to equal "<organization>/<workspace>"; otherwise it refuses to force-unlock the wrong workspace. Returned as a statemgr.LockError.
Solutions
- Run `terraform force-unlock "<organization>/<workspace>"` using the exact org and workspace name.
- Confirm the spelling and casing of org and workspace match the backend config.
- If you do have the original lock ID, use the normal unlock path instead of force-unlock.
Example fix
// before $ terraform force-unlock my-run-id // after $ terraform force-unlock "my-org/my-workspace"
Defensive patterns
Strategy: validation
Validate before calling
// Validate the force-unlock id format before calling ForceUnlock
expected := org + "/" + workspaceName
if id != expected {
return fmt.Errorf("force-unlock id must be %q, got %q", expected, id)
} Type guard
func isValidForceUnlockId(id, org, ws string) bool {
return id == org+"/"+ws
} Prevention
- Use the documented `terraform force-unlock "<org>/<workspace>"` form.
- Double-check org/workspace casing against the backend config.
- Prefer normal Unlock when the original lock ID is available.
When it happens
Trigger: r.lockInfo == nil and the user-supplied id != org/workspace: someone passed an arbitrary string to force-unlock instead of the documented org/workspace lock identifier.
Common situations: Running `terraform force-unlock <wrong-id>` after a crash; copy-paste of a run ID instead of the org/workspace string.
Related errors
- lock ID does not match existing lock
- lock ID does not match existing lock ID " /
- (lock ID: " / ")
- approved using the UI or API
- discarded using the UI or API
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/3faedea9cba4326a.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote/backend_state.go:249
return err
}
// This will not be retried
return &errorUnlockFailed{innerError: err}
}
return nil
})
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 d32a084675)