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 err

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify your flags: pass an explicit --peerAddresses value so at least one endorser is created
  2. If using a connection profile, ensure the channel section lists peers or set --targetPeer
  3. If embedding the library, ensure PeerAddresses is non-empty before calling NewClientConnections
  4. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/22edb0fb17a8d70b. Report an issue: GitHub.