hyperledger/fabric · error
consenter metadata in OrdererBlockMetadata doesn't match pro
Error message
consenter metadata in OrdererBlockMetadata doesn't match proposal
What it means
VerifyConsenterSig converts the proposal back into a block via ProposalToBlock and then validates the block's structure. This error means the proposal bytes could not be converted into a well-formed block — the proposal is malformed at the structural level (bad header, data, or metadata encoding), so no signature over it can be trusted.
Source
Thrown at orderer/consensus/smartbft/verifier.go:411
if err := proto.Unmarshal(sig.IdentifierHeader, sigHdr); err != nil {
return errors.Wrap(err, "malformed signature header")
}
if identityID != uint64(sigHdr.Identifier) {
v.Logger.Warnf("Expected identity %d but got %d", identityID,
sigHdr.Identifier)
return errors.Errorf("identity in signature header does not match expected identity")
}
// Ensure orderer block metadata's consenter MD matches the proposal
ordererMD := &cb.OrdererBlockMetadata{}
if err := proto.Unmarshal(sig.OrdererBlockMetadata, ordererMD); err != nil {
return errors.Wrap(err, "malformed orderer metadata in signature")
}
if !bytes.Equal(ordererMD.ConsenterMetadata, prop.Metadata) {
v.Logger.Warnf("Expected consenter metadata %s but got %s in proposal",
base64.StdEncoding.EncodeToString(ordererMD.ConsenterMetadata), base64.StdEncoding.EncodeToString(prop.Metadata))
return errors.Errorf("consenter metadata in OrdererBlockMetadata doesn't match proposal")
}
block, err := ProposalToBlock(prop)
if err != nil {
v.Logger.Warnf("got malformed proposal: %v", err)
return err
}
// Ensure Metadata slice is of the right size
if len(block.Metadata.Metadata) != len(cb.BlockMetadataIndex_name) {
return errors.Errorf("block metadata is of size %d but should be of size %d",
len(block.Metadata.Metadata), len(cb.BlockMetadataIndex_name))
}
signatureMetadata := &cb.Metadata{}
if err := proto.Unmarshal(block.Metadata.Metadata[cb.BlockMetadataIndex_SIGNATURES], signatureMetadata); err != nil {
return errors.Wrap(err, "malformed signature metadata")
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Reject the proposal and let the BFT layer force a view change / new proposal from a healthy leader.
- Ensure all ordering nodes run the same Fabric version so ProposalToBlock encoding is uniform.
- Inspect network/TLS integrity between orderers if corruption recurs (packet-level issues, proxies).
- If it follows a crash-recovery, rebuild the node's consensus state from the ledger or re-provision it.
Example fix
// before: proposal with missing header bytes
prop.Header = nil // ProposalToBlock fails -> error
// after: proposer always fills complete block fields
prop.Header = protoutil.MarshalOrPanic(&cb.Header{Number: blockNum, PreviousHash: prevHash, DataHash: dataHash}) Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := ProposalToBlock(prop); err != nil {
return fmt.Errorf("proposal is structurally invalid: %w", err)
} Try / catch
err := verifier.VerifyConsenterSig(sig, id)
if err != nil {
// malformed proposal: reject and force a new proposal from the leader
if errors.Is(err, ErrMalformedProposal) || strings.Contains(err.Error(), "malformed") {
triggerViewChange()
}
return err
} Prevention
- Reject malformed BFT messages at ingestion and log the sender
- Keep Fabric versions identical across the ordering service
- Protect inter-orderer links with TLS and integrity checks
When it happens
Trigger: VerifyConsenterSig -> verifySignatureIsBoundToProposal: ProposalToBlock(prop) returns an error (e.g. the proposal's Header/Data/Metadata fields are missing, wrong length, or fail internal unmarshalling). Triggered by a corrupted or hand-crafted proposal arriving in a BFT message, or a proposal produced by incompatible code.
Common situations: Corrupted network payloads between orderers; version skew where one node encodes proposals differently; tampered or fuzzed messages; storage corruption of persisted proposals after restart.
Related errors
- expected verification sequence %d, but proposal has %d
- expected metadata in block to be [view_id:%d latest_sequence
- mismatched block header
- consenter options type mismatch
- Invalid Proposal's SignatureHeader during check policy [%s]:
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/afdc1e3b8982c653.
Report an issue: GitHub.