hashicorp/terraform · error · statemgr.LockError
failed to retrieve lock info: %s
Error message
failed to retrieve lock info: %s
What it means
In RemoteClient.Unlock() (client.go:371-373), c.getLockInfo() failed before the delete. getLockInfo does a GetRow on the OTS lock row and json.Unmarshal's the Info column; failure here means the lock row cannot be read. Unlock returns a statemgr.LockError with this as Err and nil Info.
Source
Thrown at internal/backend/remote-state/oss/client.go:373
infoData = v[0].Value.(string)
}
lockInfo := &statemgr.LockInfo{}
err = json.Unmarshal([]byte(infoData), lockInfo)
if err != nil {
return nil, err
}
return lockInfo, nil
}
func (c *RemoteClient) Unlock(id string) error {
if c.otsTable == "" {
return nil
}
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
}
params := &tablestore.DeleteRowRequest{
DeleteRowChange: &tablestore.DeleteRowChange{
TableName: c.otsTable,
PrimaryKey: &tablestore.PrimaryKey{
PrimaryKeys: []*tablestore.PrimaryKeyColumn{
{
ColumnName: pkName,
Value: c.lockPath(),
},
},View on GitHub (pinned to c9def3e214)
Solutions
- Grant tablestore:GetRow on the table.
- Inspect the OTS row; if its Info JSON is corrupt, force-unlock by deleting the row directly.
- Ensure no external tool writes to the lock table's Info column.
- Recreate the OTS table if it was removed.
Example fix
# before: cannot read lock row terraform force-unlock <id> # also fails on getLockInfo # fix: delete the OTS row directly in the console (LockID = <bucket>/<stateFile>), # then re-run terraform init.
Defensive patterns
Strategy: fallback
Validate before calling
// Validate that the lock row's Info column unmarshals before attempting Unlock.
func lockInfoReadable(c *tablestore.TableStoreClient, table, path string) (*statemgr.LockInfo, error) {
// reuse getLockInfo logic; return error if Info missing/corrupt
return info, nil
} Try / catch
// If getLockInfo fails, fall back to direct OTS row deletion (force-unlock by hand).
if strings.Contains(err.Error(), "failed to retrieve lock info") {
deleteOTSLockRowManually(table, path)
} Prevention
- Grant tablestore:GetRow on the lock table.
- Never hand-edit the Info JSON column.
- Keep the OTS table present for the lifetime of the backend.
When it happens
Trigger: GetRow fails (tablestore:GetRow denied, table missing, OTS error) OR the Info column JSON fails to unmarshal into statemgr.LockInfo (corrupted/edited row). Either way the unlock cannot proceed because the code must first verify the lock ID matches (line 378).
Common situations: Lock row Info column manually edited or written by a non-terraform tool; GetRow permission missing; OTS table dropped; the lock row's Info value is empty/non-JSON.
Related errors
- getting lock info got an error: %#v
- lock id %q does not match existing lock
- error describing table store %s: %#v
- failed to lock OSS state: %s
- Error unlocking Alibaba Cloud OSS state file: Lock ID: %s E
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/35d4fd66e3640cb7.
Report an issue: GitHub.