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

  1. Convert DER to PEM: 'openssl x509 -inform der -in cert.cer -out cert.pem' and place cert.pem in the dir
  2. Remove all non-PEM files (README, .DS_Store, backups) from the MSP cert directories
  3. Validate each file: 'openssl x509 -in <file> -noout' must succeed
  4. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/4c58795d23206e71. Report an issue: GitHub.