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
- Inspect the identity certificate file at the LocalMSP signcerts path and confirm it is PEM (-----BEGIN CERTIFICATE-----)
- Re-generate or re-copy the MSP material ensuring signcerts contains a standard PEM X.509 cert and correct CA certs
- Convert DER to PEM if needed (openssl x509 -inform der -in cert.der -out cert.pem) and restart the orderer
- 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
- Check MSP signcerts contain PEM certificates (BEGIN CERTIFICATE headers)
- Convert DER certs to PEM before deploying into MSP directories
- Verify secret mounts (K8s) contain the right files, not keys or bundles
- Include an MSP/PEM sanity check in orderer startup scripts
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
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- without a system channel, a follower should have been create
- invalid PEM block
- enrollment certificate isn't a valid PEM block
- enrollment certificate should be a certificate, got a %s ins
- failed to decode PEM block from %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/937f7422af155766.
Report an issue: GitHub.