hyperledger/fabric · error
got unexpected sequence from %s - (%d) instead of (%d)
Error message
got unexpected sequence from %s - (%d) instead of (%d)
What it means
pullBlocks expects blocks from a remote orderer to arrive in strict contiguous order starting at nextExpectedSequence. If a block arrives whose Header.Number differs from the expected sequence, the pull is aborted with this error because the stream is out of sync.
Source
Thrown at orderer/common/cluster/deliver.go:239
var totalSize int
p.blockBuff = nil
nextExpectedSequence := seq
for totalSize < p.MaxTotalBufferBytes && nextExpectedSequence <= p.latestSeq {
resp, err := stream.Recv()
if err != nil {
p.Logger.Errorf("Failed receiving next block from %s: %v", p.endpoint, err)
return err
}
block, err := extractBlockFromResponse(resp)
if err != nil {
p.Logger.Errorf("Received a bad block from %s: %v", p.endpoint, err)
return err
}
seq := block.Header.Number
if seq != nextExpectedSequence {
p.Logger.Errorf("Expected to receive sequence %d but got %d instead", nextExpectedSequence, seq)
return errors.Errorf("got unexpected sequence from %s - (%d) instead of (%d)", p.endpoint, seq, nextExpectedSequence)
}
size := blockSize(block)
totalSize += size
p.blockBuff = append(p.blockBuff, block)
nextExpectedSequence++
p.Logger.Infof("[channel: %s] Got block [%d] of size %d KB from %s", p.Channel, seq, size/1024, p.endpoint)
}
return nil
}
func (p *BlockPuller) obtainStream(reConnected bool, env *common.Envelope, seq uint64) (*ImpatientStream, error) {
var stream *ImpatientStream
var err error
if reConnected {
p.Logger.Infof("Sending request for block [%d] to %s", seq, p.endpoint)
stream, err = p.requestBlocks(p.endpoint, NewImpatientStream(p.conn, p.FetchTimeout), env)
if err != nil {
return nil, errView on GitHub (pinned to 2736b63f8f)
Solutions
- Retry the pull against another orderer endpoint (standard behavior of the block puller)
- Verify the remote node is not forked/lagging and is in-sync with the cluster
- Check for channel reconfiguration/chain migration that may have altered block numbering, then re-pull from a verified height
Defensive patterns
Strategy: retry
Try / catch
block, err := puller.pullBlock(seq)
if err != nil {
if strings.Contains(err.Error(), "got unexpected sequence") {
// fall back to another endpoint and restart the pull
block, err = pullerWithNextEndpoint.pullBlock(seq)
}
} Prevention
- Pull only from orderers confirmed in-sync (probe heights first)
- Monitor chain height divergence across the cluster
- Investigate repeated sequence mismatches for forks or consensus failures
- Re-pull from a verified start sequence after any channel migration
When it happens
Trigger: During BlockPuller.pullBlocks (invoked via tryFetchBlock), the deliver stream returned block N+2 after N, or restarted at a different sequence than requested.
Common situations: Remote orderer underwent a fallback/consensus hiccup and served a different chain; the start sequence raced with block truncation on the remote node; reconnect landed on a lagging/forked node.
Related errors
- minimum requested sequence is %d but %s is at sequence %d
- block number should have been %d but was %d
- cannot create a block deliverer because height=0
- expected block number=%d, received block number=%d
- unknown orderer type: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3f11d0931cf2672b.
Report an issue: GitHub.