hyperledger/fabric · error
Failed disseminating %d out of %d private dissemination plan
Error message
Failed disseminating %d out of %d private dissemination plans
What it means
After dispatching all dissemination plans concurrently, disseminate counts send failures. If any plan failed to be sent to its designated peer(s), it returns this aggregate error so the caller (Distribute, used by the committer/gossip) knows private data dissemination was partial.
Source
Thrown at gossip/privdata/distributor.go:410
var wg sync.WaitGroup
wg.Add(len(disseminationPlan))
start := time.Now()
for _, dis := range disseminationPlan {
go func(dis *dissemination) {
defer wg.Done()
defer d.reportSendDuration(start)
err := d.SendByCriteria(dis.msg, dis.criteria)
if err != nil {
atomic.AddUint32(&failures, 1)
m := dis.msg.GetPrivateData().Payload
d.logger.Error("Failed disseminating private RWSet for TxID", m.TxId, ", namespace", m.Namespace, "collection", m.CollectionName, ":", err)
}
}(dis)
}
wg.Wait()
failureCount := atomic.LoadUint32(&failures)
if failureCount != 0 {
return errors.Errorf("Failed disseminating %d out of %d private dissemination plans", failureCount, len(disseminationPlan))
}
return nil
}
func (d *distributorImpl) reportSendDuration(startTime time.Time) {
d.metrics.SendDuration.With("channel", d.chainID).Observe(time.Since(startTime).Seconds())
}
func (d *distributorImpl) createPrivateDataMessage(txID, namespace string,
collection *rwset.CollectionPvtReadWriteSet,
ccp *peer.CollectionConfigPackage,
blkHt uint64,
) (*protoext.SignedGossipMessage, error) {
msg := &protosgossip.GossipMessage{
Channel: []byte(d.chainID),
Nonce: util.RandomUInt64(),
Tag: protosgossip.GossipMessage_CHAN_ONLY,
Content: &protosgossip.GossipMessage_PrivateData{View on GitHub (pinned to 2736b63f8f)
Solutions
- Check gossip logs on both sender and receiver for the underlying send failure
- Ensure target peers are up, reachable, and TLS-configured correctly
- Rely on private data reconciliation (reconciliationEnabled: true) to fetch missed data later; retry the commit flow
Example fix
// core.yaml privateData: reconciliationEnabled: true (peer will pull missing private data later despite dissemination failure)
Defensive patterns
Strategy: retry
Validate before calling
// pre-check connectivity
count := 0; for _, p := range plan.peers { if gossip.HasMembership(p) { count++ } } Try / catch
if err := distribute(...); err != nil {
if strings.Contains(err.Error(), "Failed disseminating") {
// enable/wait for reconciliation to recover missing pvtdata
}
} Prevention
- Enable privateData.reconciliationEnabled in core.yaml
- Keep inter-peer TLS and gossip anchors healthy
When it happens
Trigger: One or more goroutines in disseminate fail to send their signed gossip message to the target peer (peer unreachable, connection error, rejected message), incrementing the atomic failure counter.
Common situations: Target peer down or network partition; TLS handshake failures between peers; message rejected because sender lacks access or channel mismatch. Note data may still be recoverable via reconciliation/pull from other peers.
Related errors
- 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
- required to disseminate to at least %d peers, but know of on
- Empty membership
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/df6cb0eaedbe7e90.
Report an issue: GitHub.