hyperledger/fabric · critical
Error creating dir if missing: %s
Error message
Error creating dir if missing: %s
What it means
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.
Source
Thrown at common/ledger/util/leveldbhelper/leveldb_helper.go:211
return &FileLock{
filePath: filePath,
}
}
// Lock acquire a file lock. We achieve this by opening
// a db for the given filePath. Internally, leveldb acquires a
// file lock while opening a db. If the db is opened again by the same or
// another process, error would be returned. When the db is closed
// or the owner process dies, the lock would be released and hence
// the other process can open the db. We exploit this leveldb
// functionality to acquire and release file lock as the leveldb
// supports this for Windows, Solaris, and Unix.
func (f *FileLock) Lock() error {
dbOpts := &opt.Options{}
var err error
var dirEmpty bool
if dirEmpty, err = fileutil.CreateDirIfMissing(f.filePath); err != nil {
panic(fmt.Sprintf("Error creating dir if missing: %s", err))
}
dbOpts.ErrorIfMissing = !dirEmpty
db, err := leveldb.OpenFile(f.filePath, dbOpts)
if err != nil && err == syscall.EAGAIN {
return errors.Errorf("lock is already acquired on file %s", f.filePath)
}
if err != nil {
panic(fmt.Sprintf("Error acquiring lock on file %s: %s", f.filePath, err))
}
// only mutate the lock db reference AFTER validating that the lock was held.
f.db = db
return nil
}
// Determine if the lock is currently held open.
func (f *FileLock) IsLocked() bool {View on GitHub (pinned to 2736b63f8f)
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.
Example fix
// before
err := fileLock.Lock()
// after
func safeLock(fl *leveldbhelper.FileLock) (err error) {
defer func() { if r := recover(); r != nil { err = fmt.Errorf("file lock panic: %v", r) } }()
return fl.Lock()
} Defensive patterns
Strategy: validation
Validate before calling
if err := os.MkdirAll(lockDir, 0o755); err != nil {
return fmt.Errorf("cannot prepare lock dir %s: %w", lockDir, err)
}
if !writable(lockDir) { return fmt.Errorf("lock dir %s not writable", lockDir) } Type guard
func recoveredLockPanic(r interface{}) error {
if r == nil { return nil }
if s, ok := r.(string); ok && strings.HasPrefix(s, "Error creating dir") {
return errors.New(s)
}
return fmt.Errorf("unexpected panic: %v", r)
} Try / catch
func lockSafely(fl *leveldbhelper.FileLock) (err error) {
defer func() { if r := recover(); r != nil { err = fmt.Errorf("file lock failed: %v", r) } }()
return fl.Lock()
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- lock is already acquired on file %s
- Error acquiring lock on file %s: %s
- error retrieving file info for file number %d
- Error creating block storage root dir [%s]: %s
- Could not get block file info for current block file from db
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/66d4e4e3a207d3a7.
Report an issue: GitHub.