{"record":{"id":"90fb9221cf9c4cc1","repo":"hyperledger/fabric","slug":"failed-reading-directory-s","errorCode":null,"errorMessage":"failed reading directory %s","messagePattern":"failed reading directory (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/common/ccprovider/ccprovider.go","lineNumber":203,"sourceCode":"\n\treturn cccdspack, nil\n}\n\n// DirEnumerator enumerates directories\ntype DirEnumerator func(string) ([]os.DirEntry, error)\n\n// ChaincodeExtractor extracts chaincode from a given path\ntype ChaincodeExtractor func(ccNameVersion string, path string, getHasher GetHasher) (CCPackage, error)\n\n// ListInstalledChaincodes retrieves the installed chaincodes\nfunc (cifs *CCInfoFSImpl) ListInstalledChaincodes(dir string, ls DirEnumerator, ccFromPath ChaincodeExtractor) ([]chaincode.InstalledChaincode, error) {\n\tvar chaincodes []chaincode.InstalledChaincode\n\tif _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {\n\t\treturn nil, nil\n\t}\n\tfiles, err := ls(dir)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed reading directory %s\", dir)\n\t}\n\n\tfor _, f := range files {\n\t\t// Skip directories, we're only interested in normal files\n\t\tif f.IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\t// A chaincode file name is of the type \"name.version\"\n\t\t// We're only interested in the name.\n\t\t// Skip files that don't adhere to the file naming convention of \"A.B\"\n\t\ti := strings.Index(f.Name(), \".\")\n\t\tif i == -1 {\n\t\t\tccproviderLogger.Info(\"Skipping\", f.Name(), \"because of missing separator '.'\")\n\t\t\tcontinue\n\t\t}\n\t\tccName := f.Name()[:i]      // Everything before the separator\n\t\tccVersion := f.Name()[i+1:] // Everything after the separator\n","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/common/ccprovider/ccprovider.go#L185-L221","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nsudo chmod 700 /var/hyperledger/production/chaincodes\n// after\nsudo chown -R peer:peer /var/hyperledger/production/chaincodes && sudo chmod 755 /var/hyperledger/production/chaincodes","handlingStrategy":"try-catch","validationCode":"dir := \"/var/hyperledger/production/chaincodes\"\nfi, err := os.Stat(dir)\nif err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"invalid chaincode dir %s\", dir)\n}\nif _, err := os.ReadDir(dir); err != nil {\n    return fmt.Errorf(\"cannot read chaincode dir: %w\", err)\n}","typeGuard":"func isReadableDir(path string) bool {\n    fi, err := os.Stat(path)\n    return err == nil && fi.IsDir()\n}","tryCatchPattern":"chaincodes, err := ccprovider.ListInstalledChaincodes()\nif err != nil {\n    if strings.Contains(err.Error(), \"failed reading directory\") {\n        // recover: fix permissions or recreate dir, then retry once\n        return retryAfterDirRepair(err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["hyperledger-fabric","filesystem","permissions","directory"],"backgroundTag":"directory-read-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}