hyperledger/fabric · error

last config in block orderer metadata points to %d but our p

Error message

last config in block orderer metadata points to %d but our persisted last config is %d

What it means

The LastConfig.Index in the signed OrdererBlockMetadata must equal the verifier's computed/persisted last config block number. This error means the signature claims a different config block index than the verifying node's ledger says — i.e. the two nodes disagree about where the most recent configuration transaction lives, or the block references the wrong last-config pointer.

Source

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

			metadataFromProposal.GetViewId(), metadataFromProposal.GetLatestSequence(),
			metadataInBlock.GetViewId(), metadataInBlock.GetLatestSequence(),
		)
	}

	rtc := v.RuntimeConfig.Load().(RuntimeConfig)
	lastConfig := rtc.LastConfigBlock.Header.Number

	if protoutil.IsConfigBlock(block) {
		lastConfig = block.Header.Number
	}

	// Verify last config
	if ordererMetadataFromSignature.LastConfig == nil {
		return nil, errors.Errorf("last config is nil")
	}

	if ordererMetadataFromSignature.LastConfig.Index != lastConfig {
		return nil, errors.Errorf("last config in block orderer metadata points to %d but our persisted last config is %d", ordererMetadataFromSignature.LastConfig.Index, lastConfig)
	}

	rawLastConfig, err := protoutil.GetMetadataFromBlock(block, cb.BlockMetadataIndex_LAST_CONFIG)
	if err != nil {
		return nil, err
	}
	lastConf := &cb.LastConfig{}
	if err := proto.Unmarshal(rawLastConfig.Value, lastConf); err != nil {
		return nil, err
	}
	if lastConf.Index != lastConfig {
		return nil, errors.Errorf("last config in block metadata points to %d but our persisted last config is %d", ordererMetadataFromSignature.LastConfig.Index, lastConfig)
	}

	return validateTransactions(block.Data.Data, v.verifyRequest)
}

func validateTransactions(blockData [][]byte, verifyReq requestVerifier) ([]types.RequestInfo, error) {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Let the lagging node catch up: pull/replicate blocks from peers until its last config block matches the service's, then restart the orderer.
  2. Trigger a view change so the proposal is regenerated with the current last-config index.
  3. If ledgers have truly diverged, restore the node from a trusted snapshot or re-provision it from the ordering service.
  4. Verify channel config updates completed on all ordering nodes (check the config block number in each node's logs) before submitting more transactions.
  5. Check the log numbers: 'points to X but persisted Y' — if X < Y the proposer is stale; if X > Y the verifier is stale.

Example fix

// before: node's ledger last config
lastConfig = 95; signature.LastConfig.Index = 100  -> error
// after: catch up / resync node so its lastConfigIndex matches
lastConfig = 100; signature.LastConfig.Index = 100
Defensive patterns

Strategy: validation

Validate before calling

if omd.GetLastConfig().GetIndex() != localLastConfigIndex {
    // trigger catch-up/resync of this orderer before verifying further proposals
    return fmt.Errorf("last config %d != local %d", omd.GetLastConfig().GetIndex(), localLastConfigIndex)
}

Try / catch

if err := verifyProposal(prop); err != nil {
    if strings.Contains(err.Error(), "points to ") && strings.Contains(err.Error(), "last config") {
        go resyncLedgerFromService()
    }
    return err
}

Prevention

When it happens

Trigger: VerifyProposal -> verifyBlockDataAndMetadata: ordererMetadataFromSignature.LastConfig.Index != lastConfig, where lastConfig comes from the verifier's persisted last config (or the block number itself when protoutil.IsConfigBlock(block) is true). Happens when a proposal is verified against a local ledger whose last config block differs from the proposer's.

Common situations: A lagging orderer that missed the most recent channel configuration update; channel config updated while a node was down and its recorded last-config index is stale; a proposal replayed from an earlier point in the chain; divergent ledgers after a snapshot restore.

Related errors


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