hashicorp/terraform · error
failed to lock inmem state: %s
Error message
failed to lock inmem state: %s
What it means
When the in-memory backend initializes a brand-new state for a workspace it lazily acquires an init lock via s.Lock(); if that lock call fails (e.g. another holder already locked it), the wrapped error is surfaced here. This protects against two writers creating the initial empty state concurrently.
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 c9def3e214)
Solutions
- Call inmem.Reset() between tests to clear stale locks and states.
- If using the lock_id config intentionally, ensure the workspace whose state you request is not the one pre-locked, or unlock it first.
- Serialize test setup so only one writer initializes a given workspace at a time.
Example fix
// before - each test leaves locks behind, next StateMgr() fails terraform.Init(ctx) // after - reset in-memory state (and locks) between tests inmem.Reset() terraform.Init(ctx)
Defensive patterns
Strategy: validation
Validate before calling
// Ensure no pre-existing lock for the workspace before requesting a new state mgr
states.Lock(); defer states.Unlock()
if _, locked := locks.m[name]; locked {
// clear stale test lock or fail fast with a clear message
delete(locks.m, name)
}
s, diags := b.StateMgr(name) Prevention
- Call inmem.Reset() in test SetUp/TearDown to clear locks and states.
- Do not set lock_id on a workspace you then immediately initialize via StateMgr.
- Serialize concurrent initializations of the same inmem workspace.
When it happens
Trigger: Calling StateMgr(name) for a workspace that has no state yet (inmem/backend.go:132-159), where stateMgr.Lock returns an error because the global locks map already holds a lock for that name (set, for example, via the lock_id config attribute).
Common situations: A backend configured with `lock_id` in a test that pre-locks the default state, then StateMgr is called and the init lock conflicts with that pre-existing lock; concurrent test setup racing to initialize the same workspace; a stale lock left behind by a crashed test that was never Reset().
Related errors
- state locked
- state not locked
- invalid lock id
- can't delete default state
- %v Additionally, unlocking the state in Kubernetes faile
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/e4805fb081976b4c.
Report an issue: GitHub.