hashicorp/terraform · error · statemgr.LockError
getting lock info got an error: %#v
Error message
getting lock info got an error: %#v
What it means
In RemoteClient.Lock() (client.go:196-199), after PutRow already failed, the follow-up getLockInfo() call also failed; the two errors are joined with errors.Join. The leading newline is intentional so the lock-info failure appears on a new line beneath the PutRow failure. It means the client cannot even report who holds the conflicting lock.
Source
Thrown at internal/backend/remote-state/oss/client.go:198
ColumnName: "Info",
Value: string(info.Marshal()),
},
},
Condition: &tablestore.RowCondition{
RowExistenceExpectation: tablestore.RowExistenceExpectation_EXPECT_NOT_EXIST,
},
}
log.Printf("[DEBUG] Recording state lock in tablestore: %#v; LOCKID:%s", putParams, c.lockPath())
_, err := c.otsClient.PutRow(&tablestore.PutRowRequest{
PutRowChange: putParams,
})
if err != nil {
err = fmt.Errorf("invoking PutRow got an error: %#v", err)
lockInfo, infoErr := c.getLockInfo()
if infoErr != nil {
err = errors.Join(err, fmt.Errorf("\ngetting lock info got an error: %#v", infoErr))
}
lockErr := &statemgr.LockError{
Err: err,
Info: lockInfo,
}
log.Printf("[ERROR] state lock error: %s", lockErr.Error())
return "", lockErr
}
return info.ID, nil
}
func (c *RemoteClient) getMD5() ([]byte, error) {
if c.otsTable == "" {
return nil, nil
}
getParams := &tablestore.SingleRowQueryCriteria{View on GitHub (pinned to c9def3e214)
Solutions
- Grant the credentials both tablestore:PutRow and tablestore:GetRow on the table.
- Confirm the OTS table exists at ots_endpoint.
- Retry once OTS recovers; inspect the TableStore row manually to find the holder.
- If the row is stale, force-unlock by deleting the LockID row directly in the OTS console.
Example fix
// before: policy missing GetRow // Action: "tablestore:PutRow" only // after: // Action: ["tablestore:PutRow", "tablestore:GetRow", "tablestore:DeleteRow"]
Defensive patterns
Strategy: fallback
Validate before calling
// Ensure GetRow is permitted alongside PutRow, and the table exists, before locking.
func otsReadable(c *tablestore.TableStoreClient, table string) error {
_, err := c.DescribeTable(&tablestore.DescribeTableRequest{TableName: table})
return err
} Try / catch
// If the compound error shows both PutRow + GetRow failures, fall back to
// manual OTS row inspection in the console before retrying terraform.
if strings.Contains(err.Error(), "getting lock info got an error") {
return manualOTSCleanup()
} Prevention
- Grant the full lock lifecycle: tablestore:PutRow + GetRow + DeleteRow together.
- Do not delete the OTS table while applies are in flight.
- Monitor OTS health before locking-heavy operations.
When it happens
Trigger: PutRow failed (e.g. conditional conflict or permission error) AND the subsequent GetRow to read the existing Info column also failed (table missing, tablestore:GetRow denied, OTS outage). The user gets a compound error with no lock attribution.
Common situations: RAM policy grants PutRow but not GetRow; OTS table deleted between the two calls; OTS regional outage affecting both reads and writes; credentials expired mid-lock attempt.
Related errors
- failed to retrieve lock info: %s
- error describing table store %s: %#v
- failed to lock OSS state: %s
- Error unlocking Alibaba Cloud OSS state file: Lock ID: %s E
- invoking PutRow got an error: %#v
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/01f20e2a479f36fe.
Report an issue: GitHub.