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

  1. Check gossip logs on both sender and receiver for the underlying send failure
  2. Ensure target peers are up, reachable, and TLS-configured correctly
  3. 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

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


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