hashicorp/terraform · error
Lock ID should be numerical value, got
Error message
Lock ID should be numerical value, got '%s'
What it means
Thrown by Unlock when the supplied lock ID cannot be parsed as a 64-bit integer. GCS lock IDs are object generation numbers (numeric), so Unlock strconv.ParseInt's the id before using it as a GenerationMatch precondition.
Solutions
- Re-read the lock info from the lock file and copy the numeric ID/generation exactly.
- Run `terraform force-unlock` and let it read the ID from state rather than typing it.
- Verify the lock file JSON's 'ID' field is the generation number.
Example fix
// before terraform force-unlock tf-default // after — use the numeric generation from the lock file terraform force-unlock 1234567890
Defensive patterns
Strategy: validation
Validate before calling
// Validate the lock ID is numeric before calling Unlock.
if _, err := strconv.ParseInt(id, 10, 64); err != nil {
return fmt.Errorf("lock ID %q is not the numeric generation; copy ID from the lock file", id)
} Type guard
func isNumericLockID(id string) bool {
_, err := strconv.ParseInt(id, 10, 64)
return err == nil
} Prevention
- Let `terraform force-unlock` read the ID from state instead of typing it.
- Always copy the 'ID' field from the lock file JSON verbatim.
- Never substitute a UUID or workspace name for the GCS generation number.
When it happens
Trigger: Unlock(id) is called with a non-numeric string — e.g., a hand-typed lock ID, a UUID from a different backend, a corrupted env var, or an empty string.
Common situations: User passes the workspace name or a UUID to force-unlock instead of the numeric generation; CI script reads the wrong field from the lock file JSON; lock ID was truncated when copied.
Related errors
- Additionally, unlocking the state file on Google Cloud…
- Error unlocking Consul state. Lock ID
- is not a valid state name
- Unlocking the state file on TencentCloud cos backend…
- writing failed
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/80cb7c5dace4d8b3.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/gcs/client.go:131
}
return w.Close()
}()
if err != nil {
return "", c.lockError(fmt.Errorf("writing %q failed: %v", c.lockFileURL(), err))
}
info.ID = strconv.FormatInt(w.Attrs().Generation, 10)
return info.ID, nil
}
func (c *remoteClient) Unlock(id string) error {
ctx := context.TODO()
gen, err := strconv.ParseInt(id, 10, 64)
if err != nil {
return fmt.Errorf("Lock ID should be numerical value, got '%s'", id)
}
if err := c.lockFile().If(storage.Conditions{GenerationMatch: gen}).Delete(ctx); err != nil {
return c.lockError(err)
}
return nil
}
func (c *remoteClient) lockError(err error) *statemgr.LockError {
lockErr := &statemgr.LockError{
Err: err,
}
info, infoErr := c.lockInfo()
if infoErr != nil {
lockErr.Err = errors.Join(lockErr.Err, infoErr)
} else {View on GitHub (pinned to d32a084675)