hyperledger/fabric · error
failed reading directory %s
Error message
failed reading directory %s
What it means
ListInstalledChaincodes scans the peer's chaincode install directory with ls(dir) to enumerate installed chaincode packages. If the directory exists (os.Stat passed) but cannot be read — permissions, I/O error, or it is not actually a directory — the read error is wrapped with this message.
Source
Thrown at core/common/ccprovider/ccprovider.go:203
return cccdspack, nil
}
// DirEnumerator enumerates directories
type DirEnumerator func(string) ([]os.DirEntry, error)
// ChaincodeExtractor extracts chaincode from a given path
type ChaincodeExtractor func(ccNameVersion string, path string, getHasher GetHasher) (CCPackage, error)
// ListInstalledChaincodes retrieves the installed chaincodes
func (cifs *CCInfoFSImpl) ListInstalledChaincodes(dir string, ls DirEnumerator, ccFromPath ChaincodeExtractor) ([]chaincode.InstalledChaincode, error) {
var chaincodes []chaincode.InstalledChaincode
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
return nil, nil
}
files, err := ls(dir)
if err != nil {
return nil, errors.Wrapf(err, "failed reading directory %s", dir)
}
for _, f := range files {
// Skip directories, we're only interested in normal files
if f.IsDir() {
continue
}
// A chaincode file name is of the type "name.version"
// We're only interested in the name.
// Skip files that don't adhere to the file naming convention of "A.B"
i := strings.Index(f.Name(), ".")
if i == -1 {
ccproviderLogger.Info("Skipping", f.Name(), "because of missing separator '.'")
continue
}
ccName := f.Name()[:i] // Everything before the separator
ccVersion := f.Name()[i+1:] // Everything after the separator
View on GitHub (pinned to 2736b63f8f)
Solutions
- Fix filesystem permissions so the peer process can read the chaincode install directory
- Confirm the configured install path is a real directory ('ls -ld') and not a file or broken symlink/mount
- Check the wrapped underlying error for I/O details (EACCES, ENOTDIR, etc.)
- Restart or repair storage backing the peer's data directory if the filesystem is damaged
Example fix
// before sudo chmod 700 /var/hyperledger/production/chaincodes // after sudo chown -R peer:peer /var/hyperledger/production/chaincodes && sudo chmod 755 /var/hyperledger/production/chaincodes
Defensive patterns
Strategy: try-catch
Validate before calling
dir := "/var/hyperledger/production/chaincodes"
fi, err := os.Stat(dir)
if err != nil || !fi.IsDir() {
return fmt.Errorf("invalid chaincode dir %s", dir)
}
if _, err := os.ReadDir(dir); err != nil {
return fmt.Errorf("cannot read chaincode dir: %w", err)
} Type guard
func isReadableDir(path string) bool {
fi, err := os.Stat(path)
return err == nil && fi.IsDir()
} Try / catch
chaincodes, err := ccprovider.ListInstalledChaincodes()
if err != nil {
if strings.Contains(err.Error(), "failed reading directory") {
// recover: fix permissions or recreate dir, then retry once
return retryAfterDirRepair(err)
}
return err
} Prevention
- Run the peer as a dedicated user owning its data directories
- Monitor the chaincodes directory exists and is readable after deployments
- Avoid mounting the data dir over unreliable network storage
- Don't replace the directory with a file or symlink during maintenance
When it happens
Trigger: Calling ListInstalledChaincodes when ls(dir) returns an error, e.g. the chaincode install path is unreadable by the peer process or is a file rather than a directory.
Common situations: Directory permissions changed after security hardening; the install path misconfigured to a file or mount point that disappeared; disk/NFS errors on the peer host.
Related errors
- error while deleting the dir: %s
- error while creating the dir: %s, ensure peer has write acce
- error installing chaincode code %s:%s(%s)
- error writing output
- error reading dir %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/90fb9221cf9c4cc1.
Report an issue: GitHub.