{"record":{"id":"bbc56b372e2447f0","repo":"hyperledger/fabric","slug":"expected-metadata-in-block-to-be-view-id-d-lates","errorCode":null,"errorMessage":"expected metadata in block to be [view_id:%d latest_sequence:%d] but got [view_id:%d latest_sequence:%d]","messagePattern":"expected metadata in block to be \\[view_id:(.+?) latest_sequence:(.+?)\\] but got \\[view_id:(.+?) latest_sequence:(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/verifier.go","lineNumber":295,"sourceCode":"\tordererMetadataFromSignature := &cb.OrdererBlockMetadata{}\n\tif err := proto.Unmarshal(signatureMetadata.Value, ordererMetadataFromSignature); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshaling OrdererBlockMetadata\")\n\t}\n\n\t// Ensure the view metadata in the block signature and in the proposal are the same\n\n\tmetadataInBlock := &smartbftprotos.ViewMetadata{}\n\tif err := proto.Unmarshal(ordererMetadataFromSignature.ConsenterMetadata, metadataInBlock); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshaling smartbft metadata from block\")\n\t}\n\n\tmetadataFromProposal := &smartbftprotos.ViewMetadata{}\n\tif err := proto.Unmarshal(metadata, metadataFromProposal); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshaling smartbft metadata from proposal\")\n\t}\n\n\tif !proto.Equal(metadataInBlock, metadataFromProposal) {\n\t\treturn nil, errors.Errorf(\n\t\t\t\"expected metadata in block to be [view_id:%d latest_sequence:%d] but got [view_id:%d latest_sequence:%d]\",\n\t\t\tmetadataFromProposal.GetViewId(), metadataFromProposal.GetLatestSequence(),\n\t\t\tmetadataInBlock.GetViewId(), metadataInBlock.GetLatestSequence(),\n\t\t)\n\t}\n\n\trtc := v.RuntimeConfig.Load().(RuntimeConfig)\n\tlastConfig := rtc.LastConfigBlock.Header.Number\n\n\tif protoutil.IsConfigBlock(block) {\n\t\tlastConfig = block.Header.Number\n\t}\n\n\t// Verify last config\n\tif ordererMetadataFromSignature.LastConfig == nil {\n\t\treturn nil, errors.Errorf(\"last config is nil\")\n\t}\n","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/verifier.go#L277-L313","documentation":"In Hyperledger Fabric's SmartBFT ordering consensus, the proposer places SmartBFT ViewMetadata (view_id, latest_sequence) both in the proposal and in the block's orderer metadata. During VerifyProposal, verifyBlockDataAndMetadata unmarshals the metadata from the proposal and proto-Compares it with the metadata embedded in the block. This error means the two copies disagree, so the block header's metadata was tampered with or produced by a node on a different view/sequence than the proposal.","triggerScenarios":"VerifyProposal -> verifyBlockDataAndMetadata: proto.Equal(metadataInBlock, metadataFromProposal) is false, i.e. the ViewMetadata in the block (from the signature/verification path) has a different ViewId or LatestSequence than the metadata attached to the proposal being verified. Also triggered when the proposal's metadata bytes fail to reflect the view change (view_id bump) or sequence advance that the block already carries.","commonSituations":"A leader assembling a proposal after a view change but reusing stale block metadata; mixed Fabric versions across consenters with different metadata encoding; a corrupted or manually modified block; nodes catching up after a crash so their persisted view_id/latest_sequence diverge from the channel's actual view.","solutions":["Confirm all consenters run the same Fabric version (SmartBFT metadata format changed across releases) and upgrade stragglers.","Restart the ordering service so the node re-enters the current view and regenerates consistent proposal metadata.","If a leader repeatedly produces this mismatch, force a view change (leader timeout/election) to elect a healthy leader.","Check on-disk ledger integrity of the block metadata; restore the node from a snapshot/backup if corruption is suspected.","Compare ViewId/LatestSequence in the log message to determine whether the divergence is a view change (view_id) or sequence lag (latest_sequence) and fix accordingly (stale leader vs. slow node)."],"exampleFix":"// before (stale leader proposal metadata after view change)\nmetadataFromProposal: {ViewId: 3, LatestSequence: 120}\nmetadataInBlock:      {ViewId: 4, LatestSequence: 120}  -> error\n// after: force leader re-proposal in the current view so both carry ViewId 4\nmetadataFromProposal: {ViewId: 4, LatestSequence: 120}\nmetadataInBlock:      {ViewId: 4, LatestSequence: 120}","handlingStrategy":"validation","validationCode":"md := &common.ViewMetadata{}\nif err := proto.Unmarshal(metadataInBlock, md); err != nil { return err }\nif md.GetViewId() != currentView || md.GetLatestSequence() != currentSeq {\n    return fmt.Errorf(\"block metadata view/seq %d/%d != current %d/%d\", md.GetViewId(), md.GetLatestSequence(), currentView, currentSeq)\n}","typeGuard":null,"tryCatchPattern":"result, err := verifier.VerifyProposal(prop)\nif err != nil {\n    if strings.Contains(err.Error(), \"expected metadata in block\") {\n        // force view change / re-sync before retrying\n    }\n    return err\n}","preventionTips":["Keep all consenters on the same Fabric version","After a view change, always re-propose with freshly generated metadata","Monitor view_id/latest_sequence in logs to catch lagging nodes early"],"tags":["hyperledger-fabric","smartbft","consensus","block-metadata"],"backgroundTag":"block-metadata-mismatch","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"}