{"record":{"id":"8e51b055f467f53e","repo":"hyperledger/fabric","slug":"requested-to-send-to-at-least-d-peers-but-know-o","errorCode":null,"errorMessage":"requested to send to at least %d peers, but know only of %d suitable peers","messagePattern":"requested to send to at least (.+?) peers, but know only of (.+?) suitable peers","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gossip/gossip/gossip_impl.go","lineNumber":650,"sourceCode":"\t}\n\n\tif criteria.IsEligible == nil {\n\t\tcriteria.IsEligible = filter.SelectAllPolicy\n\t}\n\n\tmembership := g.disc.GetMembership()\n\n\tif len(criteria.Channel) > 0 {\n\t\tgc := g.chanState.getGossipChannelByChainID(criteria.Channel)\n\t\tif gc == nil {\n\t\t\treturn fmt.Errorf(\"requested to Send for channel %s, but no such channel exists\", criteria.Channel)\n\t\t}\n\t\tmembership = gc.GetPeers()\n\t}\n\n\tpeers2send := filter.SelectPeers(criteria.MaxPeers, membership, criteria.IsEligible)\n\tif len(peers2send) < criteria.MinAck {\n\t\treturn fmt.Errorf(\"requested to send to at least %d peers, but know only of %d suitable peers\", criteria.MinAck, len(peers2send))\n\t}\n\n\tresults := g.comm.SendWithAck(msg, criteria.Timeout, criteria.MinAck, peers2send...)\n\n\tfor _, res := range results {\n\t\tif res.Error() == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tg.logger.Warning(\"Failed sending to\", res.Endpoint, \"error:\", res.Error())\n\t}\n\n\tif results.AckCount() < criteria.MinAck {\n\t\treturn errors.New(results.String())\n\t}\n\treturn nil\n}\n\n// Gossip sends a message to other peers to the network","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/gossip/gossip/gossip_impl.go#L632-L668","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Lower criteria.MinAck to a value ≤ the number of suitable peers (typically ≤ len(membership))","Check channel membership size before sending and adjust MinAck dynamically","Relax criteria.IsEligible (e.g. use SelectAllPolicy) so more peers qualify as send targets"],"exampleFix":"// before\ncriteria := SendCriteria{Channel: ch, MinAck: 5, MaxPeers: 5, Timeout: time.Second}\n\n// after\nmembership := gc.GetPeers()\nminAck := 5\nif len(membership) < minAck {\n    minAck = len(membership)\n}\ncriteria.MinAck = minAck","handlingStrategy":"validation","validationCode":"if criteria.MinAck > criteria.MaxPeers {\n    return errors.New(\"MinAck cannot exceed MaxPeers\")\n}\n// optionally clamp to membership size\nif membership := g.disc.GetMembership(); len(membership) < criteria.MinAck {\n    criteria.MinAck = len(membership)\n}\nerr := g.SendByCriteria(msg, criteria)","typeGuard":null,"tryCatchPattern":"if err := g.SendByCriteria(msg, criteria); err != nil && strings.Contains(err.Error(), \"know only of\") {\n    criteria.MinAck = 1 // degrade gracefully on small networks\n    err = g.SendByCriteria(msg, criteria)\n}","preventionTips":["Size MinAck relative to actual channel membership before sending","Avoid overly strict IsEligible filters in small networks","Handle this error by lowering MinAck and retrying once"],"tags":["gossip","hyperledger-fabric","network"],"backgroundTag":"insufficient-peers","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}