hyperledger/fabric · warning
Empty membership
Error message
Empty membership
What it means
The private data puller fetches missing private data from channel members. After waiting for membership and applying the collection policy filters, if no remaining peer matches any collection policy, there is no one to request data from and fetchPrivateData aborts.
Source
Thrown at gossip/privdata/pull.go:256
func (p *puller) FetchReconciledItems(dig2collectionConfig privdatacommon.Dig2CollectionConfig) (*privdatacommon.FetchedPvtDataContainer, error) {
// computeFilters returns a map from a digest to a routing filter
dig2Filter, err := p.computeReconciliationFilters(dig2collectionConfig)
if err != nil {
return nil, errors.WithStack(err)
}
return p.fetchPrivateData(dig2Filter)
}
func (p *puller) fetchPrivateData(dig2Filter digestToFilterMapping) (*privdatacommon.FetchedPvtDataContainer, error) {
// Get a list of peers per channel
allFilters := dig2Filter.flattenFilterValues()
members := p.waitForMembership()
p.logger.Debug("Total members in channel:", members)
members = filter.AnyMatch(members, allFilters...)
p.logger.Debug("Total members that fit some digest:", members)
if len(members) == 0 {
p.logger.Warning("Do not know any peer in the channel(", p.channel, ") that matches the policies , aborting")
return nil, errors.New("Empty membership")
}
members = randomizeMemberList(members)
res := &privdatacommon.FetchedPvtDataContainer{}
// Distribute requests to peers, and obtain subscriptions for all their messages
// matchDigestToPeer returns a map from a peer to the digests which we would ask it for
var peer2digests peer2Digests
// We expect all private RWSets represented as digests to be collected
itemsLeftToCollect := len(dig2Filter)
// As long as we still have some data to collect and new members to ask the data for:
for itemsLeftToCollect > 0 && len(members) > 0 {
purgedPvt := p.getPurgedCollections(members, dig2Filter)
// Need to remove purged digest from mapping
for _, dig := range purgedPvt {
res.PurgedElements = append(res.PurgedElements, &protosgossip.PvtDataDigest{
TxId: dig.TxId,
BlockSeq: dig.BlockSeq,
SeqInBlock: dig.SeqInBlock,
Namespace: dig.Namespace,View on GitHub (pinned to 2736b63f8f)
Solutions
- Start at least one peer belonging to the collection's member orgs and ensure gossip connects this peer to it
- Verify this peer's org is included in the collection's member_orgs_policy if it should have access
- Wait for gossip membership convergence after channel join and retry reconciliation
Defensive patterns
Strategy: retry
Validate before calling
if len(gossip.PeersOfChannel(channel)) == 0 {
// defer fetch until membership exists
} Try / catch
res, err := puller.Fetch(retryOpts)
if err != nil && strings.Contains(err.Error(), "Empty membership") {
// retry after gossip membership converges
} Prevention
- Configure anchor peers so membership populates
- Ensure this peer's org is in the collections' member_orgs_policy
When it happens
Trigger: fetch/FetchReconciledItems runs while membership (after AnyMatch with all collection filters) is empty — no peers in the channel view are authorized for any of the missing collections.
Common situations: Peer just joined and gossip membership is empty or not converged; this peer is not a member of any collection (filters exclude everyone it knows); all collection members are offline.
Related errors
- required to disseminate to at least %d peers, but know of on
- membership is empty
- collection config package for %s chaincode is not provided
- Could not obtain collection access policy, collection name %
- No collection access policy filter computed for %v
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/66e8835834bf1032.
Report an issue: GitHub.