hyperledger/fabric · error

requested to send to at least %d peers, but know only of %d

Error message

requested to send to at least %d peers, but know only of %d suitable peers

What it means

After filtering membership with the eligibility policy, SendByCriteria checks that the number of suitable peers meets criteria.MinAck. This guards SendWithAck, which needs at least MinAck reachable peers to fulfill the acknowledgment contract; if fewer peers qualify, the send cannot possibly collect enough acks.

Source

Thrown at gossip/gossip/gossip_impl.go:650

	}

	if criteria.IsEligible == nil {
		criteria.IsEligible = filter.SelectAllPolicy
	}

	membership := g.disc.GetMembership()

	if len(criteria.Channel) > 0 {
		gc := g.chanState.getGossipChannelByChainID(criteria.Channel)
		if gc == nil {
			return fmt.Errorf("requested to Send for channel %s, but no such channel exists", criteria.Channel)
		}
		membership = gc.GetPeers()
	}

	peers2send := filter.SelectPeers(criteria.MaxPeers, membership, criteria.IsEligible)
	if len(peers2send) < criteria.MinAck {
		return fmt.Errorf("requested to send to at least %d peers, but know only of %d suitable peers", criteria.MinAck, len(peers2send))
	}

	results := g.comm.SendWithAck(msg, criteria.Timeout, criteria.MinAck, peers2send...)

	for _, res := range results {
		if res.Error() == "" {
			continue
		}
		g.logger.Warning("Failed sending to", res.Endpoint, "error:", res.Error())
	}

	if results.AckCount() < criteria.MinAck {
		return errors.New(results.String())
	}
	return nil
}

// Gossip sends a message to other peers to the network

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Lower criteria.MinAck to a value ≤ the number of suitable peers (typically ≤ len(membership))
  2. Check channel membership size before sending and adjust MinAck dynamically
  3. Relax criteria.IsEligible (e.g. use SelectAllPolicy) so more peers qualify as send targets

Example fix

// before
criteria := SendCriteria{Channel: ch, MinAck: 5, MaxPeers: 5, Timeout: time.Second}

// after
membership := gc.GetPeers()
minAck := 5
if len(membership) < minAck {
    minAck = len(membership)
}
criteria.MinAck = minAck
Defensive patterns

Strategy: validation

Validate before calling

if criteria.MinAck > criteria.MaxPeers {
    return errors.New("MinAck cannot exceed MaxPeers")
}
// optionally clamp to membership size
if membership := g.disc.GetMembership(); len(membership) < criteria.MinAck {
    criteria.MinAck = len(membership)
}
err := g.SendByCriteria(msg, criteria)

Try / catch

if err := g.SendByCriteria(msg, criteria); err != nil && strings.Contains(err.Error(), "know only of") {
    criteria.MinAck = 1 // degrade gracefully on small networks
    err = g.SendByCriteria(msg, criteria)
}

Prevention

When it happens

Trigger: Calling SendByCriteria with MinAck greater than the count of peers returned by filter.SelectPeers for the (channel-scoped) membership — e.g. MinAck: 5 with only 3 peers in the channel, or an eligibility filter that excludes most peers.

Common situations: Small test networks where MinAck exceeds the actual peer count; overly strict IsEligible policies that filter out all members; peers in a channel going down leaving membership below MinAck.

Related errors


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