hashicorp/terraform · error
failed to lock inmem state
Error message
failed to lock inmem state: %s
What it means
Thrown during inmem StateMgr initialization when acquiring the initial lock on a freshly created state fails (backend.go:144-148). The inmem backend takes a lock (lockInfo.Operation = "init") to replicate other backends; if s.Lock returns an error, the StateMgr cannot be set up. The %s is the lock error.
Solutions
- Ensure only one goroutine accesses a given inmem workspace at a time.
- Guarantee prior operations call Unlock even on error paths (proper defer/cleanup).
- In tests, use distinct workspace names per parallel test or serialize access.
- Recreate the inmem backend between tests to start with a clean lock table.
Defensive patterns
Strategy: retry
Try / catch
// _, diags := b.StateMgr(name)
// for _, d := range diags {
// if strings.Contains(d.Description().Summary, "failed to lock inmem state") {
// // in-process contention; serialize access or recreate the backend
// }
// } Prevention
- Serialize goroutine access to a single inmem workspace.
- Always defer Unlock after Lock, including on error paths.
- Recreate the inmem backend between tests for a clean lock table.
When it happens
Trigger: The in-memory lock on the named workspace is already held by another goroutine when StateMgr(name) tries to lock it for init. Inmem uses an in-process lock, so this requires concurrent access within the same process.
Common situations: Concurrent tests in the same process racing on the same inmem workspace; a previous operation that failed to release its lock; a deadlock in test teardown leaving the lock held.
Related errors
- Error locking state
- invalid lock id: . current id
- lock ID does not match existing lock ( )
- lock ID ' ' does not match the existing lock ID
- (lock ID: " / ")
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/e4805fb081976b4c.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/inmem/backend.go:147
states.Lock()
defer states.Unlock()
s := states.m[name]
if s == nil {
s = &remote.State{
Client: &RemoteClient{
Name: name,
},
}
states.m[name] = s
// to most closely replicate other implementations, we are going to
// take a lock and create a new state if it doesn't exist.
lockInfo := statemgr.NewLockInfo()
lockInfo.Operation = "init"
lockID, err := s.Lock(lockInfo)
if err != nil {
return nil, diags.Append(fmt.Errorf("failed to lock inmem state: %s", err))
}
defer s.Unlock(lockID)
// If we have no state, we have to create an empty state
if v := s.State(); v == nil {
if err := s.WriteState(statespkg.NewState()); err != nil {
return nil, diags.Append(err)
}
if err := s.PersistState(nil); err != nil {
return nil, diags.Append(err)
}
}
}
return s, diags
}
type stateMap struct {View on GitHub (pinned to d32a084675)