hyperledger/fabric · error
failed to create ledger directory: %s
Error message
failed to create ledger directory: %s
What it means
NewProvider in the blkstorage package creates the ledger's block storage directory when it does not exist. If os.MkdirAll(dirPath, 0o755) fails, the underlying OS error is wrapped with "failed to create ledger directory: %s" and provider construction is aborted. This means the process cannot obtain the directory needed to store block files.
Source
Thrown at common/ledger/blkstorage/blockstore_provider.go:79
dbConf := &leveldbhelper.Conf{
DBPath: conf.getIndexDir(),
ExpectedFormat: dataFormatVersion(indexConfig),
}
p, err := leveldbhelper.NewProvider(dbConf)
if err != nil {
return nil, err
}
dirPath := conf.getChainsDir()
if _, err := os.Stat(dirPath); err != nil {
if !os.IsNotExist(err) { // NotExist is the only permitted error type
return nil, errors.Wrapf(err, "failed to read ledger directory %s", dirPath)
}
logger.Info("Creating new file ledger directory at", dirPath)
if err = os.MkdirAll(dirPath, 0o755); err != nil {
return nil, errors.Wrapf(err, "failed to create ledger directory: %s", dirPath)
}
}
stats := newStats(metricsProvider)
return &BlockStoreProvider{conf, indexConfig, p, stats}, nil
}
// Open opens a block store for given ledgerid.
// If a blockstore is not existing, this method creates one
// This method should be invoked only once for a particular ledgerid
func (p *BlockStoreProvider) Open(ledgerid string) (*BlockStore, error) {
indexStoreHandle := p.leveldbProvider.GetDBHandle(ledgerid)
return newBlockStore(ledgerid, p.conf, p.indexConfig, indexStoreHandle, p.stats)
}
// ImportFromSnapshot initializes blockstore from a previously generated snapshot
// Any failure during bootstrapping the blockstore may leave the partial loaded data
// on disk. The consumer, such as peer is expected to keep track of failures and cleanup theView on GitHub (pinned to 2736b63f8f)
Solutions
- Check the wrapped cause in the error; run mkdir -p on the ledger path as the peer's OS user and chown the directory to that user.
- Verify the parent components of the configured ledger path are directories, not files, and the filesystem is not read-only or full (df, mount).
- If running in a container, fix the volume mount ownership/mode (e.g. securityContext fsGroup or hostPath permissions).
- On SELinux systems, relabel the path (restorecon) or adjust the policy.
Example fix
// before ledgerPath: "/var/hyperledger/production/ledgersData/chains" // root-owned, peer cannot write // after (host) sudo mkdir -p /var/hyperledger/production/ledgersData/chains sudo chown -R peer:peer /var/hyperledger/production
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(dirPath)
if err == nil {
if !info.IsDir() {
return fmt.Errorf("%s exists and is not a directory", dirPath)
}
} else if !os.IsNotExist(err) {
return err
}
if err := syscall.Access(filepath.Dir(dirPath), os.O_RDWR); err != nil {
return fmt.Errorf("no write permission for parent of %s: %w", dirPath, err)
} Try / catch
store, err := blkstorage.NewProvider(...)
if err != nil {
if strings.Contains(err.Error(), "failed to create ledger directory") {
// inspect wrapped cause: permissions, parent file, read-only FS
return fmt.Errorf("ledger dir unusable at %s: %w", dirPath, err)
}
return err
} Prevention
- Provision the ledger directory with correct ownership before starting the peer.
- In containers, set fsGroup/securityContext so the mounted volume is writable by the peer user.
- Monitor disk space and mount read-write on the ledger volume.
- Never place a file where a ledger path component is expected.
When it happens
Trigger: Calling BootstrapBlockstoreFromSnapshot, New, or openBlockStorage when the parent path of dirPath is not writable, a parent path component is a regular file, the filesystem is full/read-only, or permission bits deny creation (e.g. dirPath exists only partially with wrong ownership).
Common situations: peer.fileSystemLedger path pointing into a root-owned or read-only volume (container with mounted volume lacking write permission), Docker/K8s volume mounted with wrong ownership for the peer user, disk full, SELinux/AppArmor denial, or a file existing where a directory component should be.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- error opening block file reader for file %s
- failed to read ledger directory %s
- error opening block file %s
- error seeking block file [%s] to startOffset [%d]
- error getting block file stat
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/8f53d88348c51a20.
Report an issue: GitHub.