twpayne/chezmoi · critical
open %s: failed to acquire lock: %w
Error message
open %s: failed to acquire lock: %w
What it means
open in boltpersistentstate.go:236 opens the bbolt state database with flock-based locking. On syscall.EINVAL it assumes flock(2) failed and wraps the error as "open %s: failed to acquire lock", indicating the lock could not be acquired on the state database file.
Source
Thrown at internal/chezmoi/boltpersistentstate.go:236
if err != nil {
return err
}
return b.Put(key, value)
})
}
// open opens b's database if it is not already open, creating it if needed.
func (b *BoltPersistentState) open() error {
if b.db != nil {
return nil
}
if err := MkdirAll(b.system, b.path.Dir(), fs.ModePerm); err != nil {
return err
}
switch db, err := bbolt.Open(b.path.String(), 0o600, &b.options); {
case errors.Is(err, syscall.EINVAL):
// Assume that any EINVAL error is because flock(2) failed.
return fmt.Errorf("open %s: failed to acquire lock: %w", b.path, err)
case err != nil:
return fmt.Errorf("open %s: %w", b.path, err)
default:
b.empty = false
b.db = db
return nil
}
}
View on GitHub (pinned to f901167e46)
Solutions
- Move the chezmoi state directory to a local filesystem (set CHEZMOI state dir / use default ~/.config/chezmoi).
- If on NFS/SMB, remount with local locking enabled or switch to local storage.
- Check for stale locks/other chezmoi processes holding the file; stop them and retry.
- Verify kernel/filesystem support for flock on the mount (e.g. avoid tmpfs quirks in restricted containers).
Example fix
# before: state on NFS mount export CHEZMOI_HOME=/mnt/nfs/chezmoi # after unset CHEZMOI_HOME # use default local ~/.config/chezmoi
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure state dir is on a filesystem supporting flock
st, err := os.Stat(stateDir)
if err != nil { return err }
// e.g. reject known network mounts
if strings.HasPrefix(mntType(stateDir), "nfs") {
return fmt.Errorf("state dir must be on a local filesystem")
} Try / catch
if err := state.Get(key, &v); err != nil {
if strings.Contains(err.Error(), "failed to acquire lock") {
// move state to local fs, clear stale lock, retry once
}
return err
} Prevention
- Keep chezmoistate.boltdb on a local filesystem, never NFS/SMB.
- Avoid running concurrent chezmoi processes against the same state.
- Check mount options for flock support in containers.
- Run `chezmoi doctor` to surface state path issues.
When it happens
Trigger: Calling any persistent state method (Data, Get, Delete, DeleteBucket, ForEach, CopyTo) that triggers open while bbolt.Open returns EINVAL, typically from a filesystem that does not support flock.
Common situations: Persistent state (chezmoistate.boltdb) stored on network filesystems (NFS, SMB, CIFS) or filesystems without flock support; containers mounting state dirs from unsupported volumes; two processes contending on unsupported locking.
Related errors
AI-assisted analysis of twpayne/chezmoi@f901167e46 (2026-09-01).
Data as JSON: /api/errors/9c80827be4a434a2.
Report an issue: GitHub.