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 AIX, Badger's directory lock uses an in-process flock map keyed by the PID file path. This error is returned when the same process tries to acquire the directory lock a second time with incompatible modes (e.g. a read-write lock while a lock already exists, or read-only when an existing lock is read-write), which Badger treats as 'another process is using this database'.

Source

Thrown at dir_aix.go:66

func acquireDirectoryLock(dirPath string, pidFileName string, readOnly bool) (
	*directoryLockGuard, error) {

	// Convert to absolute path so that Release still works even if we do an unbalanced
	// 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")
	}

	aixFlockMapLock.Lock()
	defer aixFlockMapLock.Unlock()

	lg := &directoryLockGuard{absPidFilePath, readOnly}

	if lock, fnd := aixFlockMap[absPidFilePath]; fnd {
		if !readOnly || lock.readOnly != readOnly {
			return nil, fmt.Errorf(
				"Cannot acquire directory lock on %q.  Another process is using this Badger database.", dirPath)
		}
		lock.count++
	} else {
		// This is the first acquirer, set up a lock file and register it.
		f, err := os.OpenFile(absPidFilePath, os.O_RDWR|os.O_CREATE, 0666)
		if err != nil {
			return nil, y.Wrapf(err, "cannot create/open pid file %q", absPidFilePath)
		}

		opts := unix.F_WRLCK
		if readOnly {
			opts = unix.F_RDLCK
		}

		flckt := unix.Flock_t{int16(opts), 0, 0, 0, 0, 0, 0}
		err = unix.FcntlFlock(uintptr(f.Fd()), unix.F_SETLK, &flckt)
		if err != nil {
			f.Close()

View on GitHub (pinned to 2a001d466f)

Solutions

  1. Close the existing Badger DB (db.Close()) before opening the same directory again.
  2. Reuse a single *DB instance (singleton) instead of calling badger.Open repeatedly on the same path.
  3. Ensure lock modes are consistent: don't open the same directory read-only while it is already open read-write (or vice versa).
  4. Use defer db.Close() so panics/early returns don't leak the lock registration in aixFlockMap.

Example fix

// before
db1, _ := badger.Open(opts)
db2, _ := badger.Open(opts) // Cannot acquire directory lock ...
// after
db1, _ := badger.Open(opts)
defer db1.Close()
// reuse db1 instead of opening db2
Defensive patterns

Strategy: try-catch

Try / catch

db, err := badger.Open(opts)
if err != nil && strings.Contains(err.Error(), "Cannot acquire directory lock") {
	log.Fatalf("badger dir already in use by this process: %v", err)
}

Prevention

When it happens

Trigger: Opening two Badger DB instances on the same directory within one process (badger.Open called twice on the same path), or mixing a readOnly open with a read-write open on the same dir in the same process.

Common situations: Tests or services that accidentally reopen the DB without closing the first handle; a read-only background job opened while the main app holds a read-write lock; leaked DB handles after panics without db.Close().

Related errors


AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05). Data as JSON: /api/errors/76c0818df8a9e4cb. Report an issue: GitHub.