{"record":{"id":"c0932b952a80b4fa","repo":"hyperledger/fabric","slug":"no-pem-data-found-in-cert-x","errorCode":null,"errorMessage":"no PEM data found in cert[% x]","messagePattern":"no PEM data found in cert\\[% x\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/util.go","lineNumber":261,"sourceCode":"\t\tif consenter == nil {\n\t\t\treturn errors.Errorf(\"metadata has nil consenter\")\n\t\t}\n\t\tif err := validateConsenterTLSCerts(consenter, verifyOpts, true); err != nil {\n\t\t\treturn errors.WithMessagef(err, \"consenter %s:%d has invalid certificate\", consenter.GetHost(), consenter.GetPort())\n\t\t}\n\t}\n\n\tif err := MetadataHasDuplication(metadata); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc parseCertificateFromBytes(cert []byte) (*x509.Certificate, error) {\n\tpemBlock, _ := pem.Decode(cert)\n\tif pemBlock == nil {\n\t\treturn &x509.Certificate{}, errors.Errorf(\"no PEM data found in cert[% x]\", cert)\n\t}\n\n\tcertificate, err := x509.ParseCertificate(pemBlock.Bytes)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"%s TLS certificate has invalid ASN1 structure %s\", err, string(pemBlock.Bytes))\n\t}\n\n\treturn certificate, nil\n}\n\nfunc parseCertificateListFromBytes(certs [][]byte) ([]*x509.Certificate, error) {\n\tvar certificateList []*x509.Certificate\n\n\tfor _, cert := range certs {\n\t\tcertificate, err := parseCertificateFromBytes(cert)\n\t\tif err != nil {\n\t\t\treturn certificateList, err\n\t\t}","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/util.go#L243-L279","documentation":"parseCertificateFromBytes decodes a consenter's TLS cert with pem.Decode; this error means the byte slice contained no PEM block, so no x509 certificate can be parsed. The message includes the raw hex of the offending bytes for diagnosis.","triggerScenarios":"validateConsenterTLSCerts called with a consenter whose ServerTlsCert or ClientTlsCert is empty, base64-encoded-only data, a DER binary without PEM armor, or random garbage.","commonSituations":"configtx.yaml pointing at the wrong file for TLS certs; pasting a certificate without BEGIN/END lines; certs stored base64 in YAML and encoded again; empty cert file on the orderer; mixing up signing cert with TLS cert in channel config.","solutions":["Inspect the hex in the message to see what bytes were actually provided (empty vs non-PEM).","Ensure ServerTlsCert and ClientTlsCert are PEM-encoded certificates (BEGIN CERTIFICATE/END CERTIFICATE) of the orderer's TLS keypair.","Re-encode the cert file as PEM (openssl x509 -in cert.der -out cert.pem) or fix the file path in the orderer config.","Regenerate the channel config update with corrected consenter certificates."],"exampleFix":"// before: raw/der bytes\nconsenter.ServerTlsCert = derBytes\n// after: PEM-encoded\ntsCertPEM := pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: derBytes})\nconsenter.ServerTlsCert = tsCertPEM","handlingStrategy":"validation","validationCode":"func isPEMCert(b []byte) bool {\n\tblock, _ := pem.Decode(b)\n\treturn block != nil && block.Type == \"CERTIFICATE\"\n}\n// apply to each consenter\nif !isPEMCert(consenter.GetServerTlsCert()) || !isPEMCert(consenter.GetClientTlsCert()) {\n\treturn errors.New(\"consenter TLS certs must be PEM-encoded certificates\")\n}","typeGuard":"func hasPEMCerts(c *etcdraft.Consenter) bool {\n\treturn isPEMCert(c.GetServerTlsCert()) && isPEMCert(c.GetClientTlsCert())\n}","tryCatchPattern":"if err := VerifyConfigMetadata(meta, opts); err != nil {\n\tif strings.Contains(err.Error(), \"no PEM data found\") {\n\t\treturn fmt.Errorf(\"replace consenter TLS cert with PEM file: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Always point config at PEM files (-----BEGIN CERTIFICATE-----) for TLS certs.","Never base64-encode certs again after storing them in YAML.","Verify cert files are non-empty on the orderer host before generating config.","Use openssl x509 -in cert.pem -noout to confirm certs parse before embedding."],"tags":["hyperledger-fabric","raft","tls","pem","certificate"],"backgroundTag":"no-pem-data-in-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"}