{"record":{"id":"4c58795d23206e71","repo":"hyperledger/fabric","slug":"no-pem-content-for-file-s","errorCode":null,"errorMessage":"no pem content for file %s","messagePattern":"no pem content for file (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/configbuilder.go","lineNumber":77,"sourceCode":"\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\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}","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/configbuilder.go#L59-L95","documentation":"readPemFile reads a file successfully but pem.Decode returns nil, meaning the file contains no valid PEM block (missing '-----BEGIN CERTIFICATE-----' armor or garbage content). The file exists but is not a PEM-encoded cert/key.","triggerScenarios":"A file inside signcerts/cacerts/admincerts/keystore/tls dirs (picked up by getPemMaterialFromDir) is not PEM — e.g. a DER-only cert, a text file, a key exported in raw format, or a stray file like README or .DS_Store.","commonSituations":"Exporting a cert from a browser/Windows store as DER, base64-without-armor files, non-PEM files dropped into MSP folders, truncation by editors or download tools.","solutions":["Convert DER to PEM: 'openssl x509 -inform der -in cert.cer -out cert.pem' and place cert.pem in the dir","Remove all non-PEM files (README, .DS_Store, backups) from the MSP cert directories","Validate each file: 'openssl x509 -in <file> -noout' must succeed","Re-export the certificate in PEM (Base64 ASCII) format rather than binary DER"],"exampleFix":"// before: DER cert copied into cacerts\n$ ls cacerts\ncert.cer          // pem.Decode fails\n// after\n$ openssl x509 -inform der -in cert.cer -out cacerts/cert.pem","handlingStrategy":"validation","validationCode":"func ensurePEM(path string) error {\n    data, err := os.ReadFile(path)\n    if err != nil { return err }\n    if pem.Decode(data) == nil {\n        return fmt.Errorf(\"%s: not PEM; convert DER via: openssl x509 -inform der -in %s -out %s.pem\", path, path, path)\n    }\n    return nil\n}\n// apply to every file in msp cert directories before setup","typeGuard":null,"tryCatchPattern":"if _, err := readPemFile(path); err != nil {\n    if strings.Contains(err.Error(), \"no pem content\") {\n        return fmt.Errorf(\"file %s is not PEM-encoded; export as Base64/PEM\", path)\n    }\n    return err\n}","preventionTips":["Export certificates in PEM format, never DER/binary","Keep non-PEM files (README, .DS_Store, backups) out of MSP dirs","Verify with 'openssl x509 -in file -noout' for each cert","Reject any MSP file lacking '-----BEGIN' armor in CI checks"],"tags":["pem","certificate","encoding","msp"],"backgroundTag":"invalid-pem-content","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"}