hyperledger/fabric · error
no pem content for file %s
Error message
no pem content for file %s
What it means
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.
Source
Thrown at msp/configbuilder.go:77
func readFile(file string) ([]byte, error) {
fileCont, err := os.ReadFile(file)
if err != nil {
return nil, errors.Wrapf(err, "could not read file %s", file)
}
return fileCont, nil
}
func readPemFile(file string) ([]byte, error) {
bytes, err := readFile(file)
if err != nil {
return nil, errors.Wrapf(err, "reading from file %s failed", file)
}
b, _ := pem.Decode(bytes)
if b == nil { // TODO: also check that the type is what we expect (cert vs key..)
return nil, errors.Errorf("no pem content for file %s", file)
}
return bytes, nil
}
func getPemMaterialFromDir(dir string) ([][]byte, error) {
mspLogger.Debugf("Reading directory %s", dir)
_, err := os.Stat(dir)
if os.IsNotExist(err) {
return nil, err
}
content := make([][]byte, 0)
files, err := os.ReadDir(dir)
if err != nil {
return nil, errors.Wrapf(err, "could not read directory %s", dir)
}View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before: DER cert copied into cacerts $ ls cacerts cert.cer // pem.Decode fails // after $ openssl x509 -inform der -in cert.cer -out cacerts/cert.pem
Defensive patterns
Strategy: validation
Validate before calling
func ensurePEM(path string) error {
data, err := os.ReadFile(path)
if err != nil { return err }
if pem.Decode(data) == nil {
return fmt.Errorf("%s: not PEM; convert DER via: openssl x509 -inform der -in %s -out %s.pem", path, path, path)
}
return nil
}
// apply to every file in msp cert directories before setup Try / catch
if _, err := readPemFile(path); err != nil {
if strings.Contains(err.Error(), "no pem content") {
return fmt.Errorf("file %s is not PEM-encoded; export as Base64/PEM", path)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- getCertFromPem error: could not decode pem bytes [%v]
- could not decode the PEM structure
- enrollment certificate isn't a valid PEM block
- enrollment certificate should be a certificate, got a %s ins
- failed to add ca-file PEM to cert pool
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/4c58795d23206e71.
Report an issue: GitHub.