{"record":{"id":"8206b3a782f4bda9","repo":"hyperledger/fabric","slug":"reading-from-file-s-failed","errorCode":null,"errorMessage":"reading from file %s failed","messagePattern":"reading from file (.+?) failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/configbuilder.go","lineNumber":72,"sourceCode":"\tOrganizationalUnitIdentifiers []*OrganizationalUnitIdentifiersConfiguration `yaml:\"OrganizationalUnitIdentifiers,omitempty\"`\n\t// NodeOUs enables the MSP to tell apart clients, peers and orderers based\n\t// on the identity's OU.\n\tNodeOUs *NodeOUs `yaml:\"NodeOUs,omitempty\"`\n}\n\nfunc readFile(file string) ([]byte, error) {\n\tfileCont, err := os.ReadFile(file)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"could not read file %s\", file)\n\t}\n\n\treturn fileCont, nil\n}\n\nfunc readPemFile(file string) ([]byte, error) {\n\tbytes, err := readFile(file)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"reading from file %s failed\", file)\n\t}\n\n\tb, _ := pem.Decode(bytes)\n\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","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/configbuilder.go#L54-L90","documentation":"readPemFile reads a file and requires its content to be PEM-decodable before returning it. This error wraps a readFile failure, so the PEM file (cert or key) referenced by the MSP config could not be read — missing file or permission problem. It is the read-stage failure; PEM decoding problems produce a different error.","triggerScenarios":"getPemMaterialFromDir enumerating cacerts/admincerts/signcerts/intermediatecerts/tls dirs and calling readPemFile on an entry that disappeared or is unreadable; loadCertificateAt reading a cert path that does not exist.","commonSituations":"Empty or half-deleted MSP directories, dangling symlinks in cert dirs, NFS/permission issues in containers, file removed between directory listing and read.","solutions":["Check the reported file exists and is readable: 'ls -l <file>' then fix path or permissions","Remove dangling symlinks and re-copy valid PEM files into the MSP cert directories","Ensure the fabric process user can traverse all directories in the path","Regenerate the MSP directory with cryptogen/fabric-ca-server if material is missing"],"exampleFix":"// before: dangling symlink in cacerts\nfiles from os.ReadDir include stale link -> readPemFile fails\n// after\n// rm cacerts/broken-link.pem\n// cp valid-ca.pem cacerts/","handlingStrategy":"validation","validationCode":"func pemFileValid(path string) error {\n    b, err := os.ReadFile(path)\n    if err != nil { return err }\n    if pem.Decode(b) == nil { return fmt.Errorf(\"%s is not PEM\", path) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"b, err := readPemFile(path)\nif err != nil {\n    if os.IsNotExist(errors.Unwrap(err)) {\n        return fmt.Errorf(\"recreate MSP: %s is missing\", path)\n    }\n    return err\n}","preventionTips":["Prune dangling symlinks and stale files from MSP cert dirs","Check readability as the user that runs the fabric process","Copy whole MSP directories (rsync -a) so symlinks and files stay consistent","Validate all PEMs with openssl before deployment"],"tags":["filesystem","pem","msp","file-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"}