hyperledger/fabric · error

node identity certificate %s is not a valid PEM

Error message

node identity certificate %s is not a valid PEM

What it means

IsChannelMember sanitizes the local node identity certificate and PEM-decodes it to extract the public key for comparison against the channel's consenter certs. If pem.Decode returns nil — the bytes are not valid PEM — this error is returned with the offending content embedded. It indicates the orderer's configured identity is not a PEM-encoded certificate.

Source

Thrown at orderer/consensus/smartbft/consenter.go:274

	bundle, err := channelconfig.NewBundleFromEnvelope(envelopeConfig, c.BCCSP)
	if err != nil {
		return false, err
	}
	oc, exists := bundle.OrdererConfig()
	if !exists {
		return false, errors.New("no orderer config in bundle")
	}
	member := false

	santizedCert, err := crypto.SanitizeX509Cert(c.Identity)
	if err != nil {
		return false, err
	}

	// Extract public key using the same approach as IsConsenterOfChannel
	bl, _ := pem.Decode(santizedCert)
	if bl == nil {
		return false, errors.Errorf("node identity certificate %s is not a valid PEM", string(santizedCert))
	}

	myPublicKey, err := cluster.ExtractPublicKeyFromCert(bl.Bytes)
	if err != nil {
		c.Logger.Warningf("Failed to extract public key from own certificate: %v", err)
		return false, err
	}

	for _, consenter := range oc.Consenters() {
		santizedCert, err := crypto.SanitizeX509Cert(consenter.Identity)
		if err != nil {
			c.Logger.Warnf("Failed to sanitize consenter %d identity: %v", consenter.Id, err)
			return false, err
		}

		// Extract public key using the same approach as IsConsenterOfChannel
		bl, _ := pem.Decode(santizedCert)
		if bl == nil {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect the identity certificate file at the LocalMSP signcerts path and confirm it is PEM (-----BEGIN CERTIFICATE-----)
  2. Re-generate or re-copy the MSP material ensuring signcerts contains a standard PEM X.509 cert and correct CA certs
  3. Convert DER to PEM if needed (openssl x509 -inform der -in cert.der -out cert.pem) and restart the orderer
  4. Verify the file contents referenced in the log message (the offending bytes are printed) to spot mounting/encoding mistakes

Example fix

// before: DER certificate in signcerts/
$ xxd msp/signcerts/cert.pem | head  # binary DER bytes

// after: convert to PEM
$ openssl x509 -inform der -in cert.der -out msp/signcerts/cert.pem
Defensive patterns

Strategy: validation

Validate before calling

// Validate the orderer identity cert is PEM before starting/joining
pemBytes, err := os.ReadFile("msp/signcerts/cert.pem")
if err != nil { return err }
if block, _ := pem.Decode(pemBytes); block == nil {
    return errors.New("signcerts does not contain a valid PEM certificate")
}
if _, err := x509.ParseCertificate(block.Bytes); err != nil {
    return fmt.Errorf("not an X.509 cert: %w", err)
}

Prevention

When it happens

Trigger: The orderer's local MSP identity (c.Identity) or the sanitized cert bytes are not PEM — e.g. General.LocalMSPDir points at DER/invalid cert files, an empty identity, or a secret mounted with wrong contents.

Common situations: Misconfigured MSP material (certificate file contains a key, concatenated certs, or base64 text); Kubernetes secrets mounted incorrectly into the MSP path; cert rotation replaced the PEM with a DER-encoded certificate.

Understand the failure class

Related errors


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