hyperledger/fabric · error
verifying tls %s cert with serial number %d
Error message
verifying tls %s cert with serial number %d
What it means
In etcdraft/util.go, before joining or verifying consenter TLS certificates, each peer's client/server certificate is verified against the channel's root CAs. If x509 Certificate.Verify fails with anything other than an (optionally ignored) expiry error, it is wrapped with the cert type (client/server), the serial number, and the underlying x509 error. The library throws it because a TLS cert that cannot chain to the channel trust anchors makes the consenter unusable for secure communication.
Source
Thrown at orderer/consensus/etcdraft/util.go:335
}, 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 err
}
if err := verify("server", serverCert, opts); err != nil {
return err
}
return nil
}
// ConsenterCertificate denotes a TLS certificate of a consenter
type ConsenterCertificate struct {
ConsenterCertificate []byteView on GitHub (pinned to 2736b63f8f)
Solutions
- Add the issuing CA of the failing cert (serial shown in the message) to the channel's TLS root CAs (and intermediates if chaining requires it) via a channel config update
- Regenerate the consenter TLS certificate from the organization's MSP CA so it chains to the configured roots
- Ensure KeyUsage/ExtKeyUsage on the cert matches its role (serverAuth/server, clientAuth/client)
- Fix host clock skew (NTP) or reissue the cert if it is expired or not yet valid
Example fix
// before: consenter TLS cert signed by CA absent from channel config // after: configtx update adding the CA // channelconfig: Orderer.Organizations.<MSP>.TLSRootCerts += new-ca.pem // then regenerate consenter cert: // fabric-ca-client gencsr --tls.keyfiles tls.key --csr.hosts orderer.example.com
Defensive patterns
Strategy: validation
Validate before calling
func validateTLSCert(certPEM, certType string, roots *x509.CertPool, serverName string) error {
block, _ := pem.Decode([]byte(certPEM))
if block == nil { return errors.New("not PEM") }
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil { return err }
opts := x509.VerifyOptions{Roots: roots, DNSName: serverName}
if certType == "client" { opts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth} }
_, err = cert.Verify(opts)
return err
} Prevention
- Keep channel TLS root/intermediate CA lists in sync with the CA that issues orderer certs
- Use SANs matching the consenter's configured host:port when issuing certs
- Check cert expiry and rotate before they lapse
- Enable NTP on all orderer nodes to avoid clock-skew validation failures
When it happens
Trigger: Calling channels/consenter verification (e.g. cluster verification in etcdraft) where a consenter's TLS client or server certificate fails Verify against the supplied VerifyOptions: unknown CA, wrong key usage, expired/not-yet-valid cert, or hostname mismatch.
Common situations: Orderer TLS certificates rotated with new intermediate CAs not listed in the channel config's TLS root CAs; cert generated for a different hostname than the consenter's configured host:port; system clock skew making a valid cert appear expired; mixing Org1-issued certs into an Org2 consenter config.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- %s TLS certificate has invalid ASN1 structure %s
- parsing tls root certs
- parsing tls intermediate certs
- parsing tls client cert of %s:%d
- parsing tls server cert of %s:%d
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/7513fef520dce276.
Report an issue: GitHub.