hyperledger/fabric · error
pem decoding failed
Error message
pem decoding failed
What it means
VerifySignature expects the identity argument to be a PEM-encoded block containing a certificate. pem.Decode returning nil means the bytes are not valid PEM (missing -----BEGIN header, base64 corruption, or already-DER input), so it fails fast with this error.
Source
Thrown at orderer/common/cluster/util.go:716
func GetTLSSessionBinding(ctx context.Context, bindingPayload []byte) ([]byte, error) {
peerInfo, ok := peer.FromContext(ctx)
if !ok {
return nil, errors.New("failed extracting stream context")
}
connState := peerInfo.AuthInfo.(credentials.TLSInfo).State
tlsBinding, err := exportKM(connState, KeyingMaterialLabel, bindingPayload)
if err != nil {
return nil, errors.Wrap(err, "failed exporting keying material")
}
return tlsBinding, nil
}
func VerifySignature(identity, msgHash, signature []byte) error {
block, _ := pem.Decode(identity)
if block == nil {
return errors.New("pem decoding failed")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return errors.Wrap(err, "key extraction failed")
}
pubKey, isECDSA := cert.PublicKey.(*ecdsa.PublicKey)
if !isECDSA {
return errors.New("not valid public key")
}
validSignature := ecdsa.VerifyASN1(pubKey, msgHash, signature)
if !validSignature {
return errors.New("signature invalid")
}
return nilView on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the identity input is the PEM certificate (-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----)
- If you have DER bytes, PEM-encode them (pem.EncodeToMemory with Type CERTIFICATE) before calling
- Check the configured cert path actually points to the signer/identity certificate, not the key or CA bundle with extra non-PEM text
- Validate with openssl x509 -in cert.pem that the file parses
Example fix
// before
err := VerifySignature(derBytes, msgHash, sig) // derBytes are raw DER
// after
pemBytes := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
err := VerifySignature(pemBytes, msgHash, sig) Defensive patterns
Strategy: validation
Validate before calling
blk, _ := pem.Decode(identityPEM)
if blk == nil || blk.Type != "CERTIFICATE" {
return errors.New("identity must be a PEM-encoded certificate")
} Type guard
func isPEMCertificate(data []byte) bool {
blk, _ := pem.Decode(data)
return blk != nil && blk.Type == "CERTIFICATE"
} Try / catch
err := cluster.VerifySignature(identityPEM, hash, sig)
if err != nil && strings.Contains(err.Error(), "pem decoding failed") {
return fmt.Errorf("identity is not PEM: check file at MSP path; %w", err)
} Prevention
- Keep certificates in PEM format in MSP/config directories
- Never manually edit cert files (strip/adding whitespace breaks base64)
- Sanity check with openssl x509 -in cert.pem at deploy time
- Distinguish cert vs key file names to avoid loading the wrong one
When it happens
Trigger: Passing raw DER bytes, an empty slice, a truncated file, or a non-certificate PEM (e.g. a private key or CSR) as the identity parameter to VerifySignature.
Common situations: Certificates read from MSP config that were stored DER-encoded; a config file path pointing to the wrong file; copying a certificate without its BEGIN/END lines; loading a key file instead of the cert file.
Related errors
- failed to PEM decode identity bytes: %s
- %s: wrong PEM encoding
- PEM decoding resulted in an empty block
- identity %s for MSP %s has trailing bytes
- pem type is %s, should be 'CERTIFICATE' or missing
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/2d409d83955eb801.
Report an issue: GitHub.