{"record":{"id":"ae27f29306e33524","repo":"hyperledger/fabric","slug":"could-not-read-directory-s","errorCode":null,"errorMessage":"could not read directory %s","messagePattern":"could not read directory (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/configbuilder.go","lineNumber":94,"sourceCode":"\tif b == nil { // TODO: also check that the type is what we expect (cert vs key..)\n\t\treturn nil, errors.Errorf(\"no pem content for file %s\", file)\n\t}\n\n\treturn bytes, nil\n}\n\nfunc getPemMaterialFromDir(dir string) ([][]byte, error) {\n\tmspLogger.Debugf(\"Reading directory %s\", dir)\n\n\t_, err := os.Stat(dir)\n\tif os.IsNotExist(err) {\n\t\treturn nil, err\n\t}\n\n\tcontent := make([][]byte, 0)\n\tfiles, err := os.ReadDir(dir)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"could not read directory %s\", dir)\n\t}\n\n\tfor _, f := range files {\n\t\tfullName := filepath.Join(dir, f.Name())\n\n\t\tf, err := os.Stat(fullName)\n\t\tif err != nil {\n\t\t\tmspLogger.Warningf(\"Failed to stat %s: %s\", fullName, err)\n\t\t\tcontinue\n\t\t}\n\t\tif f.IsDir() {\n\t\t\tcontinue\n\t\t}\n\n\t\tmspLogger.Debugf(\"Inspecting file %s\", fullName)\n\n\t\titem, err := readPemFile(fullName)\n\t\tif err != nil {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/configbuilder.go#L76-L112","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nGetLocalMspConfig(\"/etc/hyperledger/fabric/msp/signcerts\", ...) // wrong: file dir\n// after: use MSP root\nGetLocalMspConfig(\"/etc/hyperledger/fabric/msp\", bccspConfig, \"Org1MSP\")","handlingStrategy":"validation","validationCode":"func mspLayoutOk(root string) error {\n    for _, d := range []string{\"signcerts\", \"cacerts\", \"admincerts\", \"keystore\"} {\n        fi, err := os.Stat(filepath.Join(root, d))\n        if err != nil { return fmt.Errorf(\"missing %s under %s: %w\", d, root, err) }\n        if !fi.IsDir() { return fmt.Errorf(\"%s under %s is not a directory\", d, root) }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := InitCrypto(bsp, mspPath, mspID); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && os.IsNotExist(err) {\n        log.Fatalf(\"MSP dir %s not found: fix CORE_PEER_MSPCONFIGPATH or mount\", pe.Path)\n    }\n    return err\n}","preventionTips":["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"],"tags":["filesystem","msp","configuration","directory-not-found"],"backgroundTag":"file-not-found","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"}