dgraph-io/badger · error
Cannot acquire directory lock on %q. Another process is usi
Error message
Cannot acquire directory lock on %q. Another process is using this Badger database.
What it means
On Unix systems Badger locks the database directory with unix.Flock on the LOCK file. This error is wrapped when flock fails — typically because another process already holds the lock — preventing two Badger instances from opening the same directory simultaneously.
Source
Thrown at dir_unix.go:56
// chdir in the meantime.
absPidFilePath, err := filepath.Abs(filepath.Join(dirPath, pidFileName))
if err != nil {
return nil, y.Wrapf(err, "cannot get absolute path for pid lock file")
}
f, err := os.Open(dirPath)
if err != nil {
return nil, y.Wrapf(err, "cannot open directory %q", dirPath)
}
opts := unix.LOCK_EX | unix.LOCK_NB
if readOnly {
opts = unix.LOCK_SH | unix.LOCK_NB
}
err = unix.Flock(int(f.Fd()), opts)
if err != nil {
f.Close()
return nil, y.Wrapf(err,
"Cannot acquire directory lock on %q. Another process is using this Badger database.",
dirPath)
}
if !readOnly {
// Yes, we happily overwrite a pre-existing pid file. We're the
// only read-write badger process using this directory.
err = os.WriteFile(absPidFilePath, []byte(fmt.Sprintf("%d\n", os.Getpid())), 0666)
if err != nil {
f.Close()
return nil, y.Wrapf(err,
"Cannot write pid file %q", absPidFilePath)
}
}
return &directoryLockGuard{f, absPidFilePath, readOnly}, nil
}
// Release deletes the pid file and releases our lock on the directory.
func (guard *directoryLockGuard) release() error {View on GitHub (pinned to 2a001d466f)
Solutions
- Stop the other process using the directory (check with lsof <dir>/LOCK or ps) before reopening.
- Fix deployment/config so only one instance points at the data directory (or use Badger's replication/raft rather than shared disk).
- If a previous process crashed, verify no live holder exists then retry; flock is released automatically when the holder dies.
- If you only need read access, consider opening readOnly consistently, but never mix modes with a live read-write opener.
Example fix
// before
db, err := badger.Open(badger.DefaultOptions("/data/badger"))
// FATAL: Cannot acquire directory lock on "/data/badger"...
// after
// ensure the other instance is stopped, then:
db, err := badger.Open(badger.DefaultOptions("/data/badger"))
if err != nil { log.Fatalf("db in use: %v", err) }
defer db.Close() Defensive patterns
Strategy: try-catch
Validate before calling
// before opening: check no other holder
if _, err := os.Stat(filepath.Join(dir, "LOCK")); err == nil {
// run: lsof <dir>/LOCK — or attempt a probe open readOnly
} Try / catch
db, err := badger.Open(opts)
if err != nil {
if strings.Contains(err.Error(), "Cannot acquire directory lock") {
// another live process owns the dir; back off and retry later
time.Sleep(retryInterval)
return retryOpen(opts)
}
return err
} Prevention
- Use process supervision so only one instance runs against a data dir
- Detect stale holders with lsof on the LOCK file; flock releases when the holder dies
- Avoid shared volumes mounted by multiple containers/replicas
When it happens
Trigger: badger.Open on a directory already opened by another process (read-write vs read-write, or conflicting read-only modes); a stale process still holding the flock; a second app instance started against the same data directory.
Common situations: Running two replicas of a service pointed at the same DB path, a crashed/zombie process that never released the lock, containers sharing a mounted volume, or opening the DB while badger.StreamDB/tooling (badger info) holds it.
Related errors
- Cannot acquire directory lock on %q. Another process is usi
- Unable to find fid: %d
- Equality can happen only on base level: %d
- ErrConflict
- ErrRejected
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/42b17b2a90e2428a.
Report an issue: GitHub.