{"record":{"id":"5274f350efc46daf","repo":"hyperledger/fabric","slug":"minimum-requested-sequence-is-d-but-s-is-at-sequ","errorCode":null,"errorMessage":"minimum requested sequence is %d but %s is at sequence %d","messagePattern":"minimum requested sequence is (.+?) but (.+?) is at sequence (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"orderer/common/cluster/deliver.go","lineNumber":427,"sourceCode":"\t}\n\tdefer stream.abort()\n\n\tresp, err := stream.Recv()\n\tif err != nil {\n\t\tp.Logger.Errorf(\"Failed receiving the latest block from %s: %v\", endpoint, err)\n\t\treturn 0, nil, err\n\t}\n\n\tblock, err := extractBlockFromResponse(resp)\n\tif err != nil {\n\t\tp.Logger.Warningf(\"Received %v from %s: %v\", resp, endpoint, err)\n\t\treturn 0, nil, err\n\t}\n\tstream.CloseSend()\n\n\tseq := block.Header.Number\n\tif seq < minRequestedSequence {\n\t\terr = errors.Errorf(\"minimum requested sequence is %d but %s is at sequence %d\", minRequestedSequence, endpoint, seq)\n\t\tp.Logger.Infof(\"Skipping pulling from %s: %v\", endpoint, err)\n\t\treturn 0, nil, err\n\t}\n\n\tp.Logger.Infof(\"[channel: %s] %s is at block sequence of %d\", p.Channel, endpoint, seq)\n\treturn block.Header.Number, stream.Certificate, nil\n}\n\n// requestBlocks starts requesting blocks from the given endpoint, using the given ImpatientStreamCreator by sending\n// the given envelope.\n// It returns a stream that is used to pull blocks, or error if something goes wrong.\nfunc (p *BlockPuller) requestBlocks(endpoint string, newStream ImpatientStreamCreator, env *common.Envelope) (*ImpatientStream, error) {\n\tstream, err := newStream()\n\tif err != nil {\n\t\tp.Logger.Warningf(\"Failed establishing deliver stream with %s\", endpoint)\n\t\treturn nil, err\n\t}\n","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/deliver.go#L409-L445","documentation":"fetchLastBlockSeq fetches the latest block from an endpoint to decide whether to pull from it. If the remote node's latest sequence is below the minimum sequence the local node requires, the endpoint cannot help and this error is returned, causing probeEndpoint to skip it.","triggerScenarios":"probeEndpoint calls fetchLastBlockSeq with minRequestedSequence (e.g. the local height) and the remote orderer's latest block Header.Number is lower — the remote node is behind.","commonSituations":"A lagging or newly joined orderer is probed as a block source; the local node is ahead after the remote was down; probing a node of a different/forked chain.","solutions":["Let the puller skip this endpoint and pull from an up-to-date orderer instead (default behavior)","Wait for the lagging node to catch up before relying on it as a source","Check the lagging node's consensus connectivity (Raft peers/Kafka) so it resumes ordering"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"seq, cert, err := fetchLastBlockSeq(stream, endpoint)\nif err != nil && strings.Contains(err.Error(), \"minimum requested sequence\") {\n    // endpoint is behind; try the next one\n    return probeEndpoint(nextEndpoint)\n}","preventionTips":["Treat lagging nodes as pull sources of last resort","Monitor per-node block heights and alert on lag","Ensure Raft/Kafka connectivity so followers catch up quickly"],"tags":["block-sync","ordering","lagging-node"],"backgroundTag":"lagging-node","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}