{"record":{"id":"ca93a78877165ba6","repo":"hyperledger/fabric","slug":"my-consenter-certificate-s-is-not-a-valid-pem","errorCode":null,"errorMessage":"my consenter certificate %s is not a valid PEM","messagePattern":"my consenter certificate (.+?) is not a valid PEM","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/util.go","lineNumber":384,"sourceCode":"\tif err != nil {\n\t\treturn err\n\t}\n\tbundle, err := channelconfig.NewBundleFromEnvelope(envelopeConfig, conCert.CryptoProvider)\n\tif err != nil {\n\t\treturn err\n\t}\n\toc, exists := bundle.OrdererConfig()\n\tif !exists {\n\t\treturn errors.New(\"no orderer config in bundle\")\n\t}\n\tm := &etcdraft.ConfigMetadata{}\n\tif err := proto.Unmarshal(oc.ConsensusMetadata(), m); err != nil {\n\t\treturn err\n\t}\n\n\tbl, _ := pem.Decode(conCert.ConsenterCertificate)\n\tif bl == nil {\n\t\treturn errors.Errorf(\"my consenter certificate %s is not a valid PEM\", string(conCert.ConsenterCertificate))\n\t}\n\n\tmyCertDER := bl.Bytes\n\n\tvar failedMatches []string\n\tfor _, consenter := range m.GetConsenters() {\n\t\tcandidateBlock, _ := pem.Decode(consenter.GetServerTlsCert())\n\t\tif candidateBlock == nil {\n\t\t\treturn errors.Errorf(\"candidate server certificate %s is not a valid PEM\", string(consenter.GetServerTlsCert()))\n\t\t}\n\t\tsameServerCertErr := crypto.CertificatesWithSamePublicKey(myCertDER, candidateBlock.Bytes)\n\n\t\tcandidateBlock, _ = pem.Decode(consenter.GetClientTlsCert())\n\t\tif candidateBlock == nil {\n\t\t\treturn errors.Errorf(\"candidate client certificate %s is not a valid PEM\", string(consenter.GetClientTlsCert()))\n\t\t}\n\t\tsameClientCertErr := crypto.CertificatesWithSamePublicKey(myCertDER, candidateBlock.Bytes)\n","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/util.go#L366-L402","documentation":"IsConsenterOfChannel decodes the consenter's own certificate with pem.Decode; if the result is nil the bytes are not a valid PEM block, and the error embeds the raw certificate bytes as a string. The library throws it because it cannot extract the DER certificate needed to compare against the consenters listed in the channel's etcdraft ConfigMetadata.","triggerScenarios":"ConsenterCertificate.ConsenterCertificate contains an empty slice, raw DER bytes without PEM armor, a private key file, or text/garbage instead of a PEM-encoded X.509 certificate.","commonSituations":"GeneralGenesisFile/TLS genesis material misconfigured so the consenter cert field points at a key or wrong file; certificate passed as base64 instead of PEM; empty env var or mount for the consenter certificate at orderer startup.","solutions":["Point the consenter certificate configuration at a PEM-encoded X.509 certificate file (-----BEGIN CERTIFICATE-----), not a key or DER file","Regenerate the consenter certificate from the org CA and pass it as PEM (openssl x509 -in cert.crt -out cert.pem if needed)","Verify the file/env providing the cert is actually mounted and non-empty at orderer startup"],"exampleFix":"// before: raw DER or key material passed\nconCert := ConsenterCertificate{ConsenterCertificate: derBytes}\n// after: ensure PEM-encoded certificate\npemBytes, err := os.ReadFile(\"consenter-cert.pem\") // contains -----BEGIN CERTIFICATE-----\nif err != nil { return err }\nconCert := ConsenterCertificate{ConsenterCertificate: pemBytes}","handlingStrategy":"validation","validationCode":"func isPEMCertificate(b []byte) bool {\n    block, _ := pem.Decode(b)\n    if block == nil || block.Type != \"CERTIFICATE\" { return false }\n    _, err := x509.ParseCertificate(block.Bytes)\n    return err == nil\n}","typeGuard":"func hasValidConsenterCert(c ConsenterCertificate) bool {\n    return isPEMCertificate(c.ConsenterCertificate)\n}","tryCatchPattern":null,"preventionTips":["Verify cert files begin with -----BEGIN CERTIFICATE----- at deploy time","Mount/provision the consenter cert explicitly; never reuse the TLS key file","Run openssl x509 -in cert.pem -noout as a startup sanity check"],"tags":["hyperledger-fabric","etcdraft","pem","certificate"],"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"}