hashicorp/terraform · error
error unmarshaling lock info: %s
Error message
error unmarshaling lock info: %s
What it means
Raised by getLockInfo() (consul/client.go:356) when the JSON blob stored at <lockPath>/.lockinfo cannot be unmarshaled into statemgr.LockInfo. The lock-info key is meant to be the JSON-serialized LockInfo written by putLockInfo; corruption or schema drift makes unmarshal fail and the wrapped error is surfaced.
Source
Thrown at internal/backend/remote-state/consul/client.go:356
}, nil)
return err
}
func (c *RemoteClient) getLockInfo() (*statemgr.LockInfo, error) {
path := c.lockPath() + lockInfoSuffix
pair, _, err := c.Client.KV().Get(path, nil)
if err != nil {
return nil, err
}
if pair == nil {
return nil, nil
}
li := &statemgr.LockInfo{}
err = json.Unmarshal(pair.Value, li)
if err != nil {
return nil, fmt.Errorf("error unmarshaling lock info: %s", err)
}
return li, nil
}
func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) {
c.mu.Lock()
defer c.mu.Unlock()
if !c.lockState {
return "", nil
}
c.info = info
// These checks only are to ensure we strictly follow the specification.
// Terraform shouldn't ever re-lock, so provide errors for the 2 possible
// states if this is called.View on GitHub (pinned to c9def3e214)
Solutions
- Read the raw value of <lockPath>/.lockinfo in Consul to see what was actually stored.
- If it is stale or corrupt, clear the lock with `terraform force-unlock <lock-id>` (the session ID).
- As a last resort, delete the .lockinfo KV and the matching .lock KV manually, then re-run.
- Standardize the terraform version across the team to avoid LockInfo schema drift.
Defensive patterns
Strategy: try-catch
Try / catch
// Gracefully handle corrupt lock info by clearing the stale lock
if _, err := client.getLockInfo(); err != nil {
if strings.Contains(err.Error(), "error unmarshaling lock info") {
// clear the corrupt .lockinfo and .lock KVs, then force-unlock
clearConsulLock(client)
}
} Prevention
- Do not manually write to the .lockinfo KV path.
- Use a consistent terraform version across the team to avoid LockInfo schema drift.
- Prefer `terraform force-unlock` over manually deleting lock keys.
When it happens
Trigger: getLockInfo() reads pair.Value for the .lockinfo key and json.Unmarshal returns an error. Encountered when the value is truncated, non-JSON, or written by an incompatible terraform version with a different LockInfo schema.
Common situations: Manual edit/deletion of the .lockinfo KV; a crashed run left a partial write; mixing terraform versions where LockInfo fields differ; someone wrote arbitrary bytes to that key.
Related errors
- The remote state does not match the expected hash
- consul CAS failed with transaction errors: %w
- state %q already locked
- expected on 1 response value, got: %d
- state file %q locked, but could not unmarshal lock info: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/6d0087245c8b219b.
Report an issue: GitHub.