hyperledger/fabric · error
parsing tls client cert of %s:%d
Error message
parsing tls client cert of %s:%d
What it means
validateConsenterTLSCerts parses a consenter's client TLS cert from channel config with parseCertificateFromBytes; a parse failure is wrapped with 'parsing tls client cert of <host>:<port>'. It means the client_tls_cert bytes of the identified consenter are missing PEM data or not a valid ASN.1 X.509 certificate, blocking consensus metadata validation.
Source
Thrown at orderer/consensus/etcdraft/util.go:324
tlsIntermediates.AddCert(cert)
}
}
return x509.VerifyOptions{
Roots: tlsRoots,
Intermediates: tlsIntermediates,
KeyUsages: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth,
x509.ExtKeyUsageServerAuth,
},
}, nil
}
// validateConsenterTLSCerts decodes PEM cert, parses and validates it.
func validateConsenterTLSCerts(c *etcdraft.Consenter, opts x509.VerifyOptions, ignoreExpiration bool) error {
clientCert, err := parseCertificateFromBytes(c.GetClientTlsCert())
if err != nil {
return errors.Wrapf(err, "parsing tls client cert of %s:%d", c.GetHost(), c.GetPort())
}
serverCert, err := parseCertificateFromBytes(c.GetServerTlsCert())
if err != nil {
return errors.Wrapf(err, "parsing tls server cert of %s:%d", c.GetHost(), c.GetPort())
}
verify := func(certType string, cert *x509.Certificate, opts x509.VerifyOptions) error {
if _, err := cert.Verify(opts); err != nil {
if validationRes, ok := err.(x509.CertificateInvalidError); !ok || (!ignoreExpiration || validationRes.Reason != x509.Expired) {
return errors.Wrapf(err, "verifying tls %s cert with serial number %d", certType, cert.SerialNumber)
}
}
return nil
}
if err := verify("client", clientCert, opts); err != nil {
return errView on GitHub (pinned to 2736b63f8f)
Solutions
- Fix the client_tls_cert for the consenter at host:port in configtx.yaml with a valid base64 PEM certificate and re-run configtxgen/config update
- Confirm the cert was generated for the client TLS role (tls/client.crt) and matches the consenter's TLS keypair
- Decode and check the failing bytes (openssl x509 -inform pem) to see if the PEM is empty/corrupt
- Re-enroll the orderer node via fabric-ca so valid client TLS certs are issued, then regenerate channel config
Example fix
// before: server cert reused for client field client_tls_cert: "$(base64 orderer.example.com/tls/server.crt)" // after client_tls_cert: "$(base64 orderer.example.com/tls/client.crt)"
Defensive patterns
Strategy: validation
Validate before calling
// validate each consenter's client TLS cert before config update
for _, c := range metadata.Consenters {
if err := validateTLSCertBytes(c.ClientTlsCert); err != nil {
return fmt.Errorf("consenter %s:%d has invalid client tls cert: %w", c.Host, c.Port, err)
}
} Type guard
func hasValidClientTLSCert(c *etcdraft.Consenter) bool {
block, _ := pem.Decode(c.GetClientTlsCert())
return block != nil && block.Type == "CERTIFICATE"
} Try / catch
if err := ValidateConsensusMetadata(m, l, nil); err != nil {
if strings.Contains(err.Error(), "parsing tls client cert of") {
return fmt.Errorf("a consenter's client_tls_cert is malformed: %w", err)
}
return err
} Prevention
- Fill client_tls_cert from the node's tls/client.crt, never from server.crt or .key
- Base64-encode certs with `base64 -w0` to avoid newline corruption
- Keep host:port in consenter config matching the node that owns the cert
- Re-run configtxgen after any node re-enrollment to refresh cert fields
When it happens
Trigger: VerifyConfigMetadata or ValidateConsensusMetadata iterating etcdraft consenters; consenter c has a GetClientTlsCert() whose PEM decode yields no block or whose DER fails x509.ParseCertificate; the wrap adds the consenter host:port so the bad node is identifiable.
Common situations: configtx.yaml entry for an orderer has an empty or wrong client_tls_cert (key, CSR, or TLS-CA cert pasted in orderer certs field); node re-enrolled with new certs but config update not applied; manual base64 editing corrupted the value.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- parsing tls server cert of %s:%d
- cannot load client cert for consenter %s:%d: %s
- cannot load server cert for consenter %s:%d: %s
- %s TLS certificate has invalid ASN1 structure %s
- parsing tls root certs
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/77ec127e9aad5d34.
Report an issue: GitHub.