hyperledger/fabric · error

failed pulling block %d

Error message

failed pulling block %d

What it means

Raised in Synchronizer.synchronize when the block-pulling loop finished but lastPulledBlock is nil — i.e. PullBlock(seq) failed on the very first sequence (startHeight), so no block at all could be fetched from any remote consenter. It reports the sequence number that could not be pulled.

Source

Thrown at orderer/consensus/smartbft/synchronizer.go:141

			break
		}
		if protoutil.IsConfigBlock(block) {
			s.Support.WriteConfigBlock(block, nil)
		} else {
			s.Support.WriteBlockSync(block, nil)
		}
		s.Logger.Debugf("Fetched and committed block [%d] from cluster", seq)
		lastPulledBlock = block

		prevInLatestDecision := s.lastReconfig.InLatestDecision
		s.lastReconfig = s.OnCommit(lastPulledBlock)
		s.lastReconfig.InLatestDecision = s.lastReconfig.InLatestDecision || prevInLatestDecision
		seq++
		blocksFetched++
	}

	if lastPulledBlock == nil {
		return nil, errors.Errorf("failed pulling block %d", seq)
	}

	s.Logger.Infof("Finished synchronizing with cluster, fetched %d blocks, starting from block [%d], up until and including block [%d]",
		blocksFetched, startHeight, lastPulledBlock.Header.Number)

	viewMetadata, lastConfigSqn := s.getViewMetadataLastConfigSqnFromBlock(lastPulledBlock)

	s.Logger.Infof("Returning view metadata of %v, lastConfigSeq %d", viewMetadata, lastConfigSqn)
	return s.BlockToDecision(lastPulledBlock), nil
}

// computeTargetHeight compute the target height to synchronize to.
//
// heights: a slice containing the heights of accessible peers, length must be >0.
// clusterSize: the cluster size, must be >0.
func (s *Synchronizer) computeTargetHeight(heights []uint64) uint64 {
	sort.Slice(heights, func(i, j int) bool { return heights[i] > heights[j] }) // Descending
	clusterSize := len(s.Support.SharedConfig().Consenters())

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Check the wrapped/preceding log lines for the Deliver connection failure on the reported sequence
  2. Verify remote peers actually have the requested block height (their ledgers are not behind startHeight)
  3. Fix TLS/endpoint reachability for the cluster delivery service
  4. Retry synchronization once peers are reachable and caught up
Defensive patterns

Strategy: retry

Validate before calling

// Confirm peers have the needed height before pulling
neededSeq := localHeight
for _, ep := range endpoints {
    if peerHeight(ep) >= neededSeq+1 { /* this peer can serve the block */ }
}

Try / catch

resp := synchronizer.Sync()
// Sync falls back to local ledger on error; retry after connectivity is restored
if syncFailed(resp) {
    time.Sleep(backoff)
    resp = synchronizer.Sync() // retriable: transient deliver failures
}

Prevention

When it happens

Trigger: blockPuller.PullBlock(seq) returned nil for the first needed seq (targetSeq >= seq >= startHeight), typically because all remote endpoints refused the Deliver request, blocks at that height were unavailable (peers pruned/behind), or connection failures interrupted the pull before any block arrived.

Common situations: Remote orderers have lower heights than reported earlier (stale height probe); TLS/authorization failure on the Deliver stream; this node is ahead of peers so requested seq doesn't exist remotely; transient network outage during sync.

Related errors


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