{"record":{"id":"2d409d83955eb801","repo":"hyperledger/fabric","slug":"pem-decoding-failed","errorCode":null,"errorMessage":"pem decoding failed","messagePattern":"pem decoding failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/util.go","lineNumber":716,"sourceCode":"func GetTLSSessionBinding(ctx context.Context, bindingPayload []byte) ([]byte, error) {\n\tpeerInfo, ok := peer.FromContext(ctx)\n\tif !ok {\n\t\treturn nil, errors.New(\"failed extracting stream context\")\n\t}\n\tconnState := peerInfo.AuthInfo.(credentials.TLSInfo).State\n\n\ttlsBinding, err := exportKM(connState, KeyingMaterialLabel, bindingPayload)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed exporting keying material\")\n\t}\n\n\treturn tlsBinding, nil\n}\n\nfunc VerifySignature(identity, msgHash, signature []byte) error {\n\tblock, _ := pem.Decode(identity)\n\tif block == nil {\n\t\treturn errors.New(\"pem decoding failed\")\n\t}\n\n\tcert, err := x509.ParseCertificate(block.Bytes)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"key extraction failed\")\n\t}\n\n\tpubKey, isECDSA := cert.PublicKey.(*ecdsa.PublicKey)\n\tif !isECDSA {\n\t\treturn errors.New(\"not valid public key\")\n\t}\n\n\tvalidSignature := ecdsa.VerifyASN1(pubKey, msgHash, signature)\n\n\tif !validSignature {\n\t\treturn errors.New(\"signature invalid\")\n\t}\n\treturn nil","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/util.go#L698-L734","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nerr := VerifySignature(derBytes, msgHash, sig) // derBytes are raw DER\n// after\npemBytes := pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: derBytes})\nerr := VerifySignature(pemBytes, msgHash, sig)","handlingStrategy":"validation","validationCode":"blk, _ := pem.Decode(identityPEM)\nif blk == nil || blk.Type != \"CERTIFICATE\" {\n    return errors.New(\"identity must be a PEM-encoded certificate\")\n}","typeGuard":"func isPEMCertificate(data []byte) bool {\n    blk, _ := pem.Decode(data)\n    return blk != nil && blk.Type == \"CERTIFICATE\"\n}","tryCatchPattern":"err := cluster.VerifySignature(identityPEM, hash, sig)\nif err != nil && strings.Contains(err.Error(), \"pem decoding failed\") {\n    return fmt.Errorf(\"identity is not PEM: check file at MSP path; %w\", err)\n}","preventionTips":["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"],"tags":["pem","x509","crypto"],"backgroundTag":"invalid-pem-certificate","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}