hyperledger/fabric · error

expected verification sequence %d, but proposal has %d

Error message

expected verification sequence %d, but proposal has %d

What it means

VerifyProposal compares the verifier's current verification sequence (the config sequence under which signatures are verified) with the sequence recorded in the proposal. A mismatch means the proposal was produced against a stale or newer channel config, so it is rejected.

Source

Thrown at orderer/consensus/smartbft/verifier.go:117

func (v *Verifier) VerifyProposal(proposal types.Proposal) ([]types.RequestInfo, error) {
	block, err := ProposalToBlock(proposal)
	if err != nil {
		return nil, err
	}

	rtc := v.RuntimeConfig.Load().(RuntimeConfig)
	if err := verifyHashChainAndDataHash(block, rtc.LastCommittedBlockHash); err != nil {
		return nil, err
	}

	requests, err := v.verifyBlockDataAndMetadata(block, proposal.Metadata)
	if err != nil {
		return nil, err
	}

	verificationSeq := v.VerificationSequence()
	if verificationSeq != uint64(proposal.VerificationSequence) {
		return nil, errors.Errorf("expected verification sequence %d, but proposal has %d", verificationSeq, proposal.VerificationSequence)
	}

	return requests, nil
}

// RequestsFromProposal converts proposal to []RequestInfo
func (v *Verifier) RequestsFromProposal(proposal types.Proposal) []types.RequestInfo {
	block, err := ProposalToBlock(proposal)
	if err != nil {
		return []types.RequestInfo{}
	}

	if block.Data == nil {
		return []types.RequestInfo{}
	}

	var res []types.RequestInfo
	for _, txn := range block.Data.Data {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure all replicas commit the latest config block and catch up their ledger before participating
  2. Trigger re-proposal/retry: the leader will reassemble the proposal under the current verification sequence
  3. Check network connectivity of the lagging node so it receives config blocks promptly
  4. Restart the lagging orderer after ledger catch-up to refresh its runtime config
Defensive patterns

Strategy: retry

Validate before calling

seq := v.VerificationSequence()
if seq != uint64(proposal.VerificationSequence) {
    return fmt.Errorf("stale proposal: have %d want %d", proposal.VerificationSequence, seq)
}

Try / catch

if err := VerifyProposal(proposal, ...); err != nil {
    if strings.Contains(err.Error(), "expected verification sequence") {
        // wait for ledger catch-up / let leader re-propose
    }
}

Prevention

When it happens

Trigger: A node whose channel config has advanced (verification sequence bumped) receiving a proposal assembled by a leader still on the old config; partitioned or lagging consensus replicas during config updates.

Common situations: Config update (e.g. adding a consenter) committed by most nodes while one replica lags; leader election racing with a config change; replaying an old proposal after a config commit.

Related errors


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