hyperledger/fabric · error

parsing tls root certs

Error message

parsing tls root certs

What it means

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.

Source

Thrown at orderer/consensus/etcdraft/util.go:294

		certificate, err := parseCertificateFromBytes(cert)
		if err != nil {
			return certificateList, err
		}

		certificateList = append(certificateList, certificate)
	}

	return certificateList, nil
}

func createX509VerifyOptions(ordererConfig channelconfig.Orderer) (x509.VerifyOptions, error) {
	tlsRoots := x509.NewCertPool()
	tlsIntermediates := x509.NewCertPool()

	for _, org := range ordererConfig.Organizations() {
		rootCerts, err := parseCertificateListFromBytes(org.MSP().GetTLSRootCerts())
		if err != nil {
			return x509.VerifyOptions{}, errors.Wrap(err, "parsing tls root certs")
		}
		intermediateCerts, err := parseCertificateListFromBytes(org.MSP().GetTLSIntermediateCerts())
		if err != nil {
			return x509.VerifyOptions{}, errors.Wrap(err, "parsing tls intermediate certs")
		}

		for _, cert := range rootCerts {
			tlsRoots.AddCert(cert)
		}

		for _, cert := range intermediateCerts {
			tlsIntermediates.AddCert(cert)
		}
	}

	return x509.VerifyOptions{
		Roots:         tlsRoots,
		Intermediates: tlsIntermediates,

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. 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
  2. Run parseCertificateFromBytes over each org's GetTLSRootCerts locally to identify exactly which org/cert fails
  3. Regenerate the org's crypto material with cryptogen/fabric-ca and re-issue the channel config update
  4. Ensure the file used in configtx.yaml is the TLS CA cert, not an identity/signcert or key

Example fix

// before
rootCerts, err := parseCertificateListFromBytes(org.MSP().GetTLSRootCerts())
// after: pre-validate each entry so the failure names the culprit
for i, c := range org.MSP().GetTLSRootCerts() {
    if _, err := parseCertificateFromBytes(c); err != nil {
        return x509.VerifyOptions{}, errors.Wrapf(err, "org %s tls root cert[%d]", org.Name(), i)
    }
}
_ = rootCerts
Defensive patterns

Strategy: validation

Validate before calling

// validate org TLS root certs before building verify options
for _, org := range ordererConfig.Organizations() {
    for i, rc := range org.MSP().GetTLSRootCerts() {
        if !isPEMCertificate(rc) {
            return fmt.Errorf("org %s tls root cert[%d] is not valid PEM", org.Name(), i)
        }
    }
}

Type guard

func isPEMCertificate(b []byte) bool {
    block, _ := pem.Decode(b)
    return block != nil && block.Type == "CERTIFICATE"
}

Try / catch

opts, err := createX509VerifyOptions(cfg)
if err != nil {
    if strings.Contains(err.Error(), "parsing tls root certs") {
        // surface which org's MSP TLS root certs are bad before retrying config update
        return fmt.Errorf("channel config contains invalid TLS root cert in an orderer org MSP: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/b6ae5a33b7ec9066. Report an issue: GitHub.