{"record":{"id":"c340e5dd6efcb038","repo":"hyperledger/fabric","slug":"parsing-tls-intermediate-certs","errorCode":null,"errorMessage":"parsing tls intermediate certs","messagePattern":"parsing tls intermediate certs","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/util.go","lineNumber":298,"sourceCode":"\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,\n\t\tKeyUsages: []x509.ExtKeyUsage{\n\t\t\tx509.ExtKeyUsageClientAuth,\n\t\t\tx509.ExtKeyUsageServerAuth,\n\t\t},","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/util.go#L280-L316","documentation":"createX509VerifyOptions also parses each orderer org's TLS intermediate certs via parseCertificateListFromBytes; a malformed entry there is wrapped with 'parsing tls intermediate certs'. Same root cause family as the root-cert error but for the intermediate CA chain, raised during ValidateConsensusMetadata or IsChannelMember when building the x509 verify pools.","triggerScenarios":"Channel config for etcdraft consensus contains an orderer org whose MSP GetTLSIntermediateCerts returns at least one byte slice that is not a valid PEM DER X.509 certificate (call chain: createX509VerifyOptions -> parseCertificateListFromBytes -> parseCertificateFromBytes).","commonSituations":"An org configured intermediates field pointing at files that are not certs (CRLs, keys, signatures); intermediate CA cert re-exported/damaged; mixing TLS vs TLS-CA material from different crypto generations.","solutions":["Validate every file in the org's msp/tls/intermediatecerts with openssl x509 and replace/repair the bad one, then update channel config","Enumerate GetTLSIntermediateCerts per org and parse each individually to find the failing cert","If the TLS chain has no intermediates, remove the invalid entry or empty directory instead of shipping junk bytes","Regenerate intermediate CA material from fabric-ca and rebuild the MSP definition"],"exampleFix":"// before: directory contents shipped blindly into MSP config\nintermediateCerts: file(\"crypto-config/ordererOrganizations/example.com/msp/tls/intermediatecerts/*\")\n// after: only verified PEM certificates included\nintermediateCerts: [certFor(\"intermediate.crt\")] // checked with: openssl x509 -in intermediate.crt -noout","handlingStrategy":"validation","validationCode":"// validate org TLS intermediate certs before building verify options\nfor _, org := range ordererConfig.Organizations() {\n    for i, ic := range org.MSP().GetTLSIntermediateCerts() {\n        if !isPEMCertificate(ic) {\n            return fmt.Errorf(\"org %s tls intermediate 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 intermediate certs\") {\n        return fmt.Errorf(\"invalid TLS intermediate cert in orderer org MSP: %w\", err)\n    }\n    return err\n}","preventionTips":["Only place files in msp/tls/intermediatecerts that pass `openssl x509 -noout`","If your TLS hierarchy has no intermediates, ship an empty list rather than placeholder files","Match intermediate certs to the same crypto generation as the root certs","Validate MSP dirs with a script before running configtxgen"],"tags":["x509","tls","msp","intermediate-certs","hyperledger-fabric"],"backgroundTag":"invalid-tls-intermediate-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"}