hyperledger/fabric · error
failed to access client TLS configuration: %w
Error message
failed to access client TLS configuration: %w
What it means
When the deliver service is configured with SecOpts.RequireClientCert=true, createBlockDelivererCFT must load the peer's TLS client certificate to compute TLSCertHash. ClientCertificate() returns the configured client key/cert pair; if the certificate material is missing, unreadable, or inconsistent it fails and this wrapped error is returned. It signals a TLS configuration problem, not a runtime network failure.
Source
Thrown at core/deliverservice/deliveryclient.go:219
},
OrderersSourceFactory: &orderers.ConnectionSourceFactory{Overrides: d.conf.OrdererEndpointOverrides},
CryptoProvider: d.conf.CryptoProvider,
DoneC: make(chan struct{}),
Signer: d.conf.Signer,
DeliverStreamer: blocksprovider.DeliverAdapter{},
Logger: flogging.MustGetLogger("peer.blocksprovider").With("channel", chainID),
MaxRetryInterval: d.conf.DeliverServiceConfig.ReConnectBackoffThreshold,
MaxRetryDuration: d.conf.DeliverServiceConfig.ReconnectTotalTimeThreshold,
InitialRetryInterval: 100 * time.Millisecond,
MaxRetryDurationExceededHandler: func() (stopRetries bool) {
return !d.conf.IsStaticLeader
},
}
if d.conf.DeliverServiceConfig.SecOpts.RequireClientCert {
cert, err := d.conf.DeliverServiceConfig.SecOpts.ClientCertificate()
if err != nil {
return nil, fmt.Errorf("failed to access client TLS configuration: %w", err)
}
dc.TLSCertHash = util.ComputeSHA256(cert.Certificate[0])
}
dc.Initialize(d.conf.ChannelConfig)
return dc, nil
}
func (d *deliverServiceImpl) createBlockDelivererBFT(chainID string, ledgerInfo blocksprovider.LedgerInfo) (*blocksprovider.BFTDeliverer, error) {
height, err := ledgerInfo.LedgerHeight()
if err != nil {
return nil, errors.Wrapf(err, "cannot get ledger height")
}
currentBlockHash, err := ledgerInfo.GetCurrentBlockHash()
if err != nil {
return nil, errors.Wrapf(err, "cannot get current block hash")
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Set tls.clientCertFile and tls.clientKeyFile in the peer's core.yaml (SecOpts) to valid, matching PEM files when tls.clientAuthRequired is true
- Verify the files exist and are readable by the peer process (check volume mounts and file permissions in containers)
- Validate that the client certificate/key pair matches (compare public keys/moduli) and re-issue from the same CA if mismatched
- If client certs are not required by the ordering service, set RequireClientCert / tls.clientAuthRequired to false to skip loading the client cert
Example fix
# before (core.yaml) tls: clientAuthRequired: true # clientCertFile / clientKeyFile not set # after tls: clientAuthRequired: true clientCertFile: /etc/hyperledger/fabric/tls/client.crt clientKeyFile: /etc/hyperledger/fabric/tls/client.key
Defensive patterns
Strategy: validation
Validate before calling
if secOpts.RequireClientCert {
if _, err := secOpts.ClientCertificate(); err != nil {
return fmt.Errorf("invalid client TLS config: %w", err)
}
} Type guard
func hasClientCertPair(certFile, keyFile string) bool {
if certFile == "" || keyFile == "" {
return false
}
_, err := os.Stat(certFile)
_, err2 := os.Stat(keyFile)
return err == nil && err2 == nil
} Try / catch
dc, err := createBlockDeliverer(chainID)
var tlsCfgErr *TLSCertError
if errors.As(err, &tlsCfgErr) {
// fail fast: fix core.yaml tls.clientCertFile / clientKeyFile
return fmt.Errorf("peer TLS client config invalid: %w", err)
} Prevention
- Validate TLS files exist and parse at peer startup, not at first delivery
- Keep clientCertFile/clientKeyFile set whenever clientAuthRequired is true
- Mount cert/key files read-only in containers and verify permissions
- Regenerate client cert and key together to avoid mismatched pairs
When it happens
Trigger: Running with RequireClientCert=true while SecOpts has no valid client KeyFile/CertificateFile (or the loaded tls.Certificate has no cert bytes), so SecOpts.ClientCertificate() errors inside createBlockDelivererCFT via StartDeliverForChannel.
Common situations: Peer core.yaml TLS section missing tls.clientKeyFile/tls.clientCertFile while tls.clientAuthRequired is true; cert files deleted or unreadable at runtime (permissions, container mount missing); cert/key mismatch causing load failure; mutual-TLS required by orderer but peer config never updated.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- panic(err)
- Empty policy element
- cannot load client cert for consenter %s:%d: %s
- cannot load server cert for consenter %s:%d: %s
- failed to initialize block verifier function
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/cbfac449234a8ab2.
Report an issue: GitHub.