hyperledger/fabric · error
no endorser clients retrieved
Error message
no endorser clients retrieved
What it means
NewClientConnections builds endorser/deliver clients from the resolved peer connection parameters. This error is a defensive check: endorserClients ended up empty, which per the code comment should only happen due to a programming bug, since normal CLI flows guarantee at least one peer address before clients are created.
Source
Thrown at internal/peer/lifecycle/chaincode/client_connections.go:102
for i, address := range input.PeerAddresses {
var tlsRootCertFile string
if input.TLSRootCertFiles != nil {
tlsRootCertFile = input.TLSRootCertFiles[i]
}
endorserClient, err := common.GetEndorserClient(address, tlsRootCertFile)
if err != nil {
return errors.WithMessagef(err, "failed to retrieve endorser client for %s", input.CommandName)
}
endorserClients = append(endorserClients, endorserClient)
deliverClient, err := common.GetPeerDeliverClient(address, tlsRootCertFile)
if err != nil {
return errors.WithMessagef(err, "failed to retrieve deliver client for %s", input.CommandName)
}
deliverClients = append(deliverClients, deliverClient)
}
if len(endorserClients) == 0 {
// this should only be empty due to a programming bug
return errors.New("no endorser clients retrieved")
}
err := c.setCertificate()
if err != nil {
return err
}
c.EndorserClients = endorserClients
c.DeliverClients = deliverClients
return nil
}
func (c *ClientConnections) validatePeerConnectionParameters(input *ClientConnectionsInput) error {
if input.ConnectionProfilePath != "" {
err := input.parseConnectionProfile()
if err != nil {
return errView on GitHub (pinned to 2736b63f8f)
Solutions
- Verify your flags: pass an explicit --peerAddresses value so at least one endorser is created
- If using a connection profile, ensure the channel section lists peers or set --targetPeer
- If embedding the library, ensure PeerAddresses is non-empty before calling NewClientConnections
- File a bug — the code itself notes this indicates a programming bug
Example fix
// before peer lifecycle chaincode approveformyorg --connectionProfile cp.yaml --channelID mychannel ... // profile channel has no peers // after peer lifecycle chaincode approveformyorg --connectionProfile cp.yaml --targetPeer peer0.org1.example.com:7051 ...
Defensive patterns
Strategy: validation
Validate before calling
// before calling the library
if len(peerAddresses) == 0 && connectionProfilePeers() == 0 { return errors.New("at least one peer address or profile peer is required") } Type guard
func hasEndorsers(c *chaincode.ClientConnections) bool { return len(c.EndorserClients) > 0 } Try / catch
if err := chaincode.NewClientConnections(input); err != nil { if strings.Contains(err.Error(), "no endorser clients") { log.Fatal("fix input: no peer addresses were resolved") } return err } Prevention
- Always pass --peerAddresses or a complete connection profile
- When embedding, set PeerAddresses explicitly before constructing clients
- Treat this error as an input-construction bug, not a network issue
When it happens
Trigger: setPeerClients completes without returning an error but appends zero endorser clients — internally inconsistent input state (e.g. connection profile resolved to no peers but also bypassed the empty check).
Common situations: Very rare for end users; encountered mostly when embedding the lifecycle chaincode package programmatically with a hand-built ClientConnectionsInput, or a connection profile whose channel peer list is empty combined with unusual flags.
Related errors
- chaincode type not supported: %s
- failed to copy metadataDir directory folder: %s
- error unmarshalling YAML file %s: %s
- no endpoints
- subpolicy number %d type %T of policy %s is not convertible
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/22edb0fb17a8d70b.
Report an issue: GitHub.