hyperledger/fabric · error
number of peer addresses (%d) does not match the number of T
Error message
number of peer addresses (%d) does not match the number of TLS root cert files (%d)
What it means
Validation in validatePeerConnectionParameters: when TLS is enabled, each --peerAddresses must have a matching --tlsRootCertFiles entry, but the counts differ (%d vs %d). The command cannot establish authenticated connections without one root cert per peer address.
Source
Thrown at internal/peer/lifecycle/chaincode/client_connections.go:139
}
}
// currently only support multiple peer addresses for _lifecycle
// for approveformyorg and commit
multiplePeersAllowed := map[string]bool{
"approveformyorg": true,
"commit": true,
}
if !multiplePeersAllowed[input.CommandName] && len(input.PeerAddresses) > 1 {
return errors.Errorf("'%s' command supports one peer. %d peers provided", input.CommandName, len(input.PeerAddresses))
}
if !input.TLSEnabled {
input.TLSRootCertFiles = nil
return nil
}
if len(input.TLSRootCertFiles) != len(input.PeerAddresses) {
return errors.Errorf("number of peer addresses (%d) does not match the number of TLS root cert files (%d)", len(input.PeerAddresses), len(input.TLSRootCertFiles))
}
return nil
}
func (c *ClientConnectionsInput) parseConnectionProfile() error {
networkConfig, err := common.GetConfig(c.ConnectionProfilePath)
if err != nil {
return err
}
c.PeerAddresses = []string{}
c.TLSRootCertFiles = []string{}
if c.ChannelID == "" {
if c.TargetPeer == "" {
return errors.New("--targetPeer must be specified for channel-less operation using connection profile")
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Provide one --tlsRootCertFiles per --peerAddresses, in the same order
- If the network is not TLS-enabled, pass --tls false so cert checks are skipped
- Verify each cert file path exists and corresponds to the CA that signed that peer's TLS cert
Example fix
// before --peerAddresses p0:7051 --peerAddresses p1:8051 --tlsRootCertFiles ca0.pem // after --peerAddresses p0:7051 --peerAddresses p1:8051 --tlsRootCertFiles ca0.pem --tlsRootCertFiles ca1.pem
Defensive patterns
Strategy: validation
Validate before calling
if tlsEnabled && len(peerAddresses) != len(tlsRootCertFiles) { return fmt.Errorf("need %d tls root certs, got %d", len(peerAddresses), len(tlsRootCertFiles)) } Try / catch
if err := run(cmd); err != nil && strings.Contains(err.Error(), "does not match the number of TLS root cert files") { log.Fatal("pair each --peerAddresses with a --tlsRootCertFiles") } Prevention
- Build peer/cert pairs together in scripts (arrays of tuples)
- Verify each cert path exists before invoking
- If network is non-TLS, omit cert flags entirely and use --tls false
When it happens
Trigger: TLSEnabled is true and len(input.TLSRootCertFiles) != len(input.PeerAddresses) — e.g. two peer addresses but one (or zero) TLS root cert files, or certs given while TLS flags resolve differently.
Common situations: Forgetting --tlsRootCertFiles for the second --peerAddresses; using a peer address without its matching CA cert path; environment-level CORE_VM or --tls settings inconsistent across flags.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- could not connect to ordering service
- access denied
- client didn't send a TLS certificate
- client claimed TLS hash doesn't match computed TLS hash from
- trailing args detected: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b1700a7040f56295.
Report an issue: GitHub.