{"record":{"id":"439b6d66308b8c78","repo":"hyperledger/fabric","slug":"failed-obtaining-original-collection-filter-for-ch","errorCode":null,"errorMessage":"Failed obtaining original collection filter for channel %s, config %s","messagePattern":"Failed obtaining original collection filter for channel (.+?), config (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gossip/privdata/pull.go","lineNumber":507,"sourceCode":"\t\t}\n\t}\n\treturn filters, nil\n}\n\nfunc (p *puller) computeReconciliationFilters(dig2collectionConfig privdatacommon.Dig2CollectionConfig) (digestToFilterMapping, error) {\n\tfilters := make(map[privdatacommon.DigKey]collectionRoutingFilter)\n\tfor digest, originalCollectionConfig := range dig2collectionConfig {\n\t\tanyPeerInCollection, err := p.getLatestCollectionConfigRoutingFilter(digest.Namespace, digest.Collection)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\toriginalConfigFilter, err := p.cs.AccessFilter(p.channel, originalCollectionConfig.MemberOrgsPolicy)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif originalConfigFilter == nil {\n\t\t\treturn nil, errors.Errorf(\"Failed obtaining original collection filter for channel %s, config %s\", p.channel, digest.Collection)\n\t\t}\n\n\t\t// get peers that were in the collection config while the missing data was created\n\t\tpeerFromDataCreation, err := p.getMatchAllRoutingFilter(originalConfigFilter)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// prefer peers that are in the collection from the time the data was created rather than ones that were added later.\n\t\t// the assumption is that the longer the peer is in the collection config, the chances it has the data are bigger.\n\t\tpreferredPeer := func(member discovery.NetworkMember) bool {\n\t\t\treturn peerFromDataCreation(member) && anyPeerInCollection(member)\n\t\t}\n\n\t\tfilters[digest] = collectionRoutingFilter{\n\t\t\tanyPeer:       anyPeerInCollection,\n\t\t\tpreferredPeer: preferredPeer,\n\t\t}","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/gossip/privdata/pull.go#L489-L525","documentation":"During reconciliation, the puller needs the routing filter of the collection config as it existed when the missing data was created (from the digest's collection config). If AccessFilter on that original config's MemberOrgsPolicy returns nil, it cannot determine which peers may hold the data.","triggerScenarios":"computeReconciliationFilters processes a reconciliation digest whose stored/original collection config yields a nil filter from p.cs.AccessFilter(channel, MemberOrgsPolicy).","commonSituations":"Missing pvtdata from a collection whose config was later modified or removed; stale/invalid stored collection config snapshot; unsupported policy producing no filter.","solutions":["Check the stored original collection config snapshot for the missing data is valid and its MemberOrgsPolicy is well-formed","Re-verify the collection config history on the channel; update reconciliation scope or drop unobtainable data","Fix the collectionAccessStore (cs) so it returns the correct historical config"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if originalCollectionConfig == nil || originalCollectionConfig.MemberOrgsPolicy == nil { skipDigest() }","typeGuard":"func validOriginalConfig(c *peer.StaticCollectionConfig) bool { return c != nil && c.MemberOrgsPolicy != nil }","tryCatchPattern":null,"preventionTips":["Preserve valid historical collection config snapshots with missing data","Avoid removing collections that still have un-reconciled pvtdata"],"tags":["hyperledger-fabric","reconciliation","private-data","nil-filter"],"backgroundTag":"nil-collection-filter","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}