{"record":{"id":"66d4e4e3a207d3a7","repo":"hyperledger/fabric","slug":"error-creating-dir-if-missing-s","errorCode":null,"errorMessage":"Error creating dir if missing: %s","messagePattern":"Error creating dir if missing: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"common/ledger/util/leveldbhelper/leveldb_helper.go","lineNumber":211,"sourceCode":"\treturn &FileLock{\n\t\tfilePath: filePath,\n\t}\n}\n\n// Lock acquire a file lock. We achieve this by opening\n// a db for the given filePath. Internally, leveldb acquires a\n// file lock while opening a db. If the db is opened again by the same or\n// another process, error would be returned. When the db is closed\n// or the owner process dies, the lock would be released and hence\n// the other process can open the db. We exploit this leveldb\n// functionality to acquire and release file lock as the leveldb\n// supports this for Windows, Solaris, and Unix.\nfunc (f *FileLock) Lock() error {\n\tdbOpts := &opt.Options{}\n\tvar err error\n\tvar dirEmpty bool\n\tif dirEmpty, err = fileutil.CreateDirIfMissing(f.filePath); err != nil {\n\t\tpanic(fmt.Sprintf(\"Error creating dir if missing: %s\", err))\n\t}\n\tdbOpts.ErrorIfMissing = !dirEmpty\n\tdb, err := leveldb.OpenFile(f.filePath, dbOpts)\n\tif err != nil && err == syscall.EAGAIN {\n\t\treturn errors.Errorf(\"lock is already acquired on file %s\", f.filePath)\n\t}\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"Error acquiring lock on file %s: %s\", f.filePath, err))\n\t}\n\n\t// only mutate the lock db reference AFTER validating that the lock was held.\n\tf.db = db\n\n\treturn nil\n}\n\n// Determine if the lock is currently held open.\nfunc (f *FileLock) IsLocked() bool {","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/ledger/util/leveldbhelper/leveldb_helper.go#L193-L229","documentation":"FileLock.Lock panics (does not return the error) when fileutil.CreateDirIfMissing fails for the lock's directory path. The message carries the wrapped cause. This is a programmer/infrastructure failure — the lock directory could not be created or inspected — so the code deliberately crashes rather than proceeding without a lock.","triggerScenarios":"Lock directory does not exist and cannot be created (permissions, read-only filesystem, invalid path); an I/O error occurs while stat-ing/creating the directory. Reached via TestFileLock-style usage of FileLock.","commonSituations":"Running the process as a user without write access to the lock directory; incorrect configured path; container with read-only rootfs; NFS mounts lacking directory-create support.","solutions":["Create the lock directory manually and grant the process user write permission on it.","Fix the configured file lock path in configuration to a writable location.","Check that the filesystem is not mounted read-only.","Since this panics, recover at a process boundary and log f.filePath plus the cause for diagnosis."],"exampleFix":"// before\nerr := fileLock.Lock()\n// after\nfunc safeLock(fl *leveldbhelper.FileLock) (err error) {\n  defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"file lock panic: %v\", r) } }()\n  return fl.Lock()\n}","handlingStrategy":"validation","validationCode":"if err := os.MkdirAll(lockDir, 0o755); err != nil {\n  return fmt.Errorf(\"cannot prepare lock dir %s: %w\", lockDir, err)\n}\nif !writable(lockDir) { return fmt.Errorf(\"lock dir %s not writable\", lockDir) }","typeGuard":"func recoveredLockPanic(r interface{}) error {\n  if r == nil { return nil }\n  if s, ok := r.(string); ok && strings.HasPrefix(s, \"Error creating dir\") {\n    return errors.New(s)\n  }\n  return fmt.Errorf(\"unexpected panic: %v\", r)\n}","tryCatchPattern":"func lockSafely(fl *leveldbhelper.FileLock) (err error) {\n  defer func() { if r := recover(); r != nil { err = fmt.Errorf(\"file lock failed: %v\", r) } }()\n  return fl.Lock()\n}","preventionTips":["Pre-create the lock directory with correct ownership","Run the process as a user with write access to the data directory","Avoid read-only filesystems for lock/ledger paths","Always wrap FileLock.Lock in a recover since it can panic"],"tags":["leveldb","filelock","filesystem","golang","panic"],"backgroundTag":"leveldb-dir-create-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}