{"record":{"id":"b6ae5a33b7ec9066","repo":"hyperledger/fabric","slug":"parsing-tls-root-certs","errorCode":null,"errorMessage":"parsing tls root certs","messagePattern":"parsing tls root certs","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/util.go","lineNumber":294,"sourceCode":"\t\tcertificate, err := parseCertificateFromBytes(cert)\n\t\tif err != nil {\n\t\t\treturn certificateList, err\n\t\t}\n\n\t\tcertificateList = append(certificateList, certificate)\n\t}\n\n\treturn certificateList, nil\n}\n\nfunc createX509VerifyOptions(ordererConfig channelconfig.Orderer) (x509.VerifyOptions, error) {\n\ttlsRoots := x509.NewCertPool()\n\ttlsIntermediates := x509.NewCertPool()\n\n\tfor _, org := range ordererConfig.Organizations() {\n\t\trootCerts, err := parseCertificateListFromBytes(org.MSP().GetTLSRootCerts())\n\t\tif err != nil {\n\t\t\treturn x509.VerifyOptions{}, errors.Wrap(err, \"parsing tls root certs\")\n\t\t}\n\t\tintermediateCerts, err := parseCertificateListFromBytes(org.MSP().GetTLSIntermediateCerts())\n\t\tif err != nil {\n\t\t\treturn x509.VerifyOptions{}, errors.Wrap(err, \"parsing tls intermediate certs\")\n\t\t}\n\n\t\tfor _, cert := range rootCerts {\n\t\t\ttlsRoots.AddCert(cert)\n\t\t}\n\n\t\tfor _, cert := range intermediateCerts {\n\t\t\ttlsIntermediates.AddCert(cert)\n\t\t}\n\t}\n\n\treturn x509.VerifyOptions{\n\t\tRoots:         tlsRoots,\n\t\tIntermediates: tlsIntermediates,","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/util.go#L276-L312","documentation":"createX509VerifyOptions builds x509 verification pools from every orderer organization's MSP TLS root certs. It first parses each org's GetTLSRootCerts via parseCertificateListFromBytes; any malformed certificate there is wrapped with 'parsing tls root certs'. The error indicates a bad TLS root certificate in an orderer org's MSP definition, so x509.VerifyOptions cannot be constructed.","triggerScenarios":"ValidateConsensusMetadata or IsChannelMember reading channel config whose orderer org MSP contains an invalid PEM/DER entry in its TLS root certs list (call chain: createX509VerifyOptions -> parseCertificateListFromBytes -> parseCertificateFromBytes -> underlying ASN1/PEM error).","commonSituations":"crypto-config regeneration left a stale tlscacerts file; configtx.yaml references a PEM containing a private key or CSR; a cert was base64-encoded twice; org admin uploaded a corrupted root cert to the MSP folder.","solutions":["Fix the invalid TLS root cert in the offending org's MSP dir (validate each: openssl x509 -in tls/ca.crt -noout) and update channel config","Run parseCertificateFromBytes over each org's GetTLSRootCerts locally to identify exactly which org/cert fails","Regenerate the org's crypto material with cryptogen/fabric-ca and re-issue the channel config update","Ensure the file used in configtx.yaml is the TLS CA cert, not an identity/signcert or key"],"exampleFix":"// before\nrootCerts, err := parseCertificateListFromBytes(org.MSP().GetTLSRootCerts())\n// after: pre-validate each entry so the failure names the culprit\nfor i, c := range org.MSP().GetTLSRootCerts() {\n    if _, err := parseCertificateFromBytes(c); err != nil {\n        return x509.VerifyOptions{}, errors.Wrapf(err, \"org %s tls root cert[%d]\", org.Name(), i)\n    }\n}\n_ = rootCerts","handlingStrategy":"validation","validationCode":"// validate org TLS root certs before building verify options\nfor _, org := range ordererConfig.Organizations() {\n    for i, rc := range org.MSP().GetTLSRootCerts() {\n        if !isPEMCertificate(rc) {\n            return fmt.Errorf(\"org %s tls root cert[%d] is not valid PEM\", org.Name(), i)\n        }\n    }\n}","typeGuard":"func isPEMCertificate(b []byte) bool {\n    block, _ := pem.Decode(b)\n    return block != nil && block.Type == \"CERTIFICATE\"\n}","tryCatchPattern":"opts, err := createX509VerifyOptions(cfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"parsing tls root certs\") {\n        // surface which org's MSP TLS root certs are bad before retrying config update\n        return fmt.Errorf(\"channel config contains invalid TLS root cert in an orderer org MSP: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep msp/tlscacerts (TLS CA) separate from admincerts/signcerts (identity certs)","Regenerate all orgs' crypto material together so roots stay consistent","Inspect every org's tls root cert with openssl before channel creation","Version-control crypto-config and diff after regeneration"],"tags":["x509","tls","msp","root-certs","hyperledger-fabric"],"backgroundTag":"invalid-tls-root-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"}