{"record":{"id":"ea0f43d1e099b58f","repo":"nsqio/nsq","slug":"cannot-flock-directory-s-s-possibly-in-use-by","errorCode":null,"errorMessage":"cannot flock directory %s - %s (possibly in use by another instance of nsqd)","messagePattern":"cannot flock directory (.+?) - (.+?) \\(possibly in use by another instance of nsqd\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/dirlock/dirlock.go","lineNumber":31,"sourceCode":"\tdir string\n\tf   *os.File\n}\n\nfunc New(dir string) *DirLock {\n\treturn &DirLock{\n\t\tdir: dir,\n\t}\n}\n\nfunc (l *DirLock) Lock() error {\n\tf, err := os.Open(l.dir)\n\tif err != nil {\n\t\treturn err\n\t}\n\tl.f = f\n\terr = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot flock directory %s - %s (possibly in use by another instance of nsqd)\", l.dir, err)\n\t}\n\treturn nil\n}\n\nfunc (l *DirLock) Unlock() error {\n\terr := syscall.Flock(int(l.f.Fd()), syscall.LOCK_UN)\n\tcloseErr := l.f.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn closeErr\n}\n","sourceCodeStart":13,"sourceCodeEnd":44,"githubUrl":"https://github.com/nsqio/nsq/blob/85cf10c09c6c3c86160d6f0eb156f62d0efc1648/internal/dirlock/dirlock.go#L13-L44","documentation":"internal/dirlock wraps an exclusive, non-blocking flock (syscall.Flock with LOCK_EX|LOCK_NB) on the directory fd of nsqd's --data-path; Lock returns 'cannot flock directory %s - %s (possibly in use by another instance of nsqd)' when the flock syscall itself errors. Its purpose is to stop two nsqd processes from sharing one data directory and corrupting disk-backed queue state. The wrapped syscall error distinguishes the causes: EWOULDBLOCK means another holder exists; other errnos mean the filesystem does not support flock at all.","triggerScenarios":"Starting a second nsqd with the same --data-path (EWOULDBLOCK/EAGAIN); or running the data path on a filesystem that cannot flock a directory: NFS without a lock manager, some network/FUSE mounts, older CIFS setups, or certain container volumes (EROFS/EOPNOTSUPP-style errors). The directory must already exist — a missing dir fails earlier at os.Open.","commonSituations":"Accidentally launching a duplicate systemd/docker instance after a config edit; running nsqd on NFS-mounted storage 'for shared persistence'; k8s hostPath/RWO volume attached twice; test scripts that forgot to kill the previous nsqd and reuse /tmp dirs.","solutions":["Find and stop the other process: 'fuser -v <data-path>' / 'ps aux | grep nsqd' / 'lsof +D <data-path>', then start nsqd again.","Give each nsqd instance its own --data-path (the standard fix for fleets and local parallel runs).","Move the data path off network/FUSE filesystems onto local disk (ext4/xfs) — flock on a directory must be supported.","If you truly need shared storage, do not share one dir between live nsqd processes; architect replication with nsqd nodes instead."],"exampleFix":"# before: two instances, same dir\nnsqd --data-path=/var/lib/nsq ...   # instance A running\nnsqd --data-path=/var/lib/nsq ...   # instance B -> cannot flock directory ...\n\n# after: separate data paths (or stop the old instance first)\nnsqd --data-path=/var/lib/nsq-a ...\nnsqd --data-path=/var/lib/nsq-b ...","handlingStrategy":"validation","validationCode":"// pre-start: assert no other nsqd holds the data dir and the fs supports flock\nfunc canLockDataDir(dir string) error {\n    f, err := os.Open(dir)\n    if err != nil {\n        return err\n    }\n    defer f.Close()\n    if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {\n        return fmt.Errorf(\"data dir %s busy or unsupported fs: %w\", dir, err)\n    }\n    return syscall.Flock(int(f.Fd()), syscall.LOCK_UN)\n}","typeGuard":null,"tryCatchPattern":"// orchestrators: catch startup failure and name the two causes\nif err := startNsqd(cfg); err != nil && strings.Contains(err.Error(), \"cannot flock directory\") {\n    if errors.Is(err, syscall.EWOULDBLOCK) {\n    \treturn errors.New(\"another nsqd owns this data-path; stop it or assign a new --data-path\")\n    }\n    return errors.New(\"data-path filesystem does not support flock; use local disk\")\n}","preventionTips":["Give every nsqd a unique --data-path by construction (hostname suffix).","Never place --data-path on NFS/FUSE mounts.","Have init systems/executors stop the old instance before starting a replacement."],"tags":["filesystem","flock","startup","nsqd","single-instance","configuration"],"backgroundTag":null,"analyzedSha":"85cf10c09c6c3c86160d6f0eb156f62d0efc1648","analyzedAt":"2026-08-16T00:53:05.009Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}