hyperledger/fabric · error
could not read directory %s
Error message
could not read directory %s
What it means
getPemMaterialFromDir lists a certificate directory with os.ReadDir and fails when the directory cannot be read — it does not exist, is a file instead of a directory, or lacks permissions. The error wraps the OS error with the directory path.
Source
Thrown at msp/configbuilder.go:94
if b == nil { // TODO: also check that the type is what we expect (cert vs key..)
return nil, errors.Errorf("no pem content for file %s", file)
}
return bytes, nil
}
func getPemMaterialFromDir(dir string) ([][]byte, error) {
mspLogger.Debugf("Reading directory %s", dir)
_, err := os.Stat(dir)
if os.IsNotExist(err) {
return nil, err
}
content := make([][]byte, 0)
files, err := os.ReadDir(dir)
if err != nil {
return nil, errors.Wrapf(err, "could not read directory %s", dir)
}
for _, f := range files {
fullName := filepath.Join(dir, f.Name())
f, err := os.Stat(fullName)
if err != nil {
mspLogger.Warningf("Failed to stat %s: %s", fullName, err)
continue
}
if f.IsDir() {
continue
}
mspLogger.Debugf("Inspecting file %s", fullName)
item, err := readPemFile(fullName)
if err != nil {View on GitHub (pinned to 2736b63f8f)
Solutions
- Confirm the directory exists and is a directory: 'ls -ld <dir>'; correct CORE_PEER_MSPCONFIGPATH or the dir argument
- Point the config at the MSP root (the dir containing signcerts/, cacerts/, etc.), not a cert file
- Fix permissions: ensure the running user can read/traverse every path component
- In containers, verify the volume mount for the MSP directory is present and correct
Example fix
// before
GetLocalMspConfig("/etc/hyperledger/fabric/msp/signcerts", ...) // wrong: file dir
// after: use MSP root
GetLocalMspConfig("/etc/hyperledger/fabric/msp", bccspConfig, "Org1MSP") Defensive patterns
Strategy: validation
Validate before calling
func mspLayoutOk(root string) error {
for _, d := range []string{"signcerts", "cacerts", "admincerts", "keystore"} {
fi, err := os.Stat(filepath.Join(root, d))
if err != nil { return fmt.Errorf("missing %s under %s: %w", d, root, err) }
if !fi.IsDir() { return fmt.Errorf("%s under %s is not a directory", d, root) }
}
return nil
} Try / catch
if err := InitCrypto(bsp, mspPath, mspID); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && os.IsNotExist(err) {
log.Fatalf("MSP dir %s not found: fix CORE_PEER_MSPCONFIGPATH or mount", pe.Path)
}
return err
} Prevention
- Point config at the MSP root directory, never at a single file
- Stat the directory before starting the node or calling the API
- Verify container volume mounts for /etc/hyperledger/fabric/msp
- Ensure execute permission on every parent directory of the MSP path
When it happens
Trigger: GetLocalMspConfig/getMspConfig calling getPemMaterialFromDir on signcerts/cacerts/admincerts/keystore paths when CORE_PEER_MSPCONFIGPATH points to a nonexistent or wrong-structure directory; getIdentity in idemix reading a missing dir.
Common situations: MSP path typo in peer/orderer config, MSP volume not mounted in a container, pointing at a single file rather than the MSP root directory, running as a user without execute permission on parent dirs.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- cannot init crypto, specified path "%s" does not exist or ca
- cannot init crypto, specified path "%s" is not a directory
- could not read file %s
- could not load signing certificate from directory %s
- Error creating block storage root dir [%s]: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/ae27f29306e33524.
Report an issue: GitHub.