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 the

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. 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.
  2. Verify the parent components of the configured ledger path are directories, not files, and the filesystem is not read-only or full (df, mount).
  3. If running in a container, fix the volume mount ownership/mode (e.g. securityContext fsGroup or hostPath permissions).
  4. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/8f53d88348c51a20. Report an issue: GitHub.