hyperledger/fabric · error
malformed orderer metadata in signature
Error message
malformed orderer metadata in signature
What it means
The consenter metadata (opaque consensus-related bytes) inside the signature's OrdererBlockMetadata must byte-match the metadata attached to the proposal. This error means the signature was computed over different consenter metadata than what the proposal carries, so the signature cannot be bound to this proposal.
Source
Thrown at orderer/consensus/smartbft/verifier.go:405
base64.StdEncoding.EncodeToString(sig.BlockHeader))
return errors.Errorf("mismatched block header")
}
// Ensure signature header matches the identity
sigHdr := &cb.IdentifierHeader{}
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))View on GitHub (pinned to 2736b63f8f)
Solutions
- Drop the mismatched signature and re-request signature collection for the current proposal.
- Upgrade all consenters to the same Fabric version to ensure identical consenter metadata encoding.
- Force a view change so a fresh proposal with consistent consenter metadata is proposed and signed.
- If persistent, enable BFT debug logs and compare the base64 metadata from the log line to identify which field differs.
Example fix
// before ordererMD.ConsenterMetadata = "old-rotation-md"; prop.Metadata = "new-rotation-md" -> error // after: signer embeds proposal's metadata verbatim ordererMD.ConsenterMetadata = prop.Metadata
Defensive patterns
Strategy: validation
Validate before calling
if !bytes.Equal(ordererMD.GetConsenterMetadata(), prop.Metadata) {
return errors.New("signature consenter metadata differs from proposal; request fresh signature")
} Try / catch
err := verifier.VerifyConsenterSig(sig, id)
if err != nil && strings.Contains(err.Error(), "doesn't match proposal") {
// drop signature, trigger re-proposal/view change
} Prevention
- Signers must embed the proposal's metadata bytes verbatim
- Upgrade stragglers so consenter metadata encoding is uniform
- After leader rotation, require fresh proposals before signature collection
When it happens
Trigger: VerifyConsenterSig -> verifySignatureIsBoundToProposal: bytes.Equal(ordererMD.ConsenterMetadata, prop.Metadata) is false — the OrdererBlockMetadata in the signature holds different consenter metadata bytes than prop.Metadata. Triggered by replayed signatures from another proposal or by a signing node that embedded different consenter metadata (e.g. different leader/rotation info) than the proposer.
Common situations: Mixed Fabric versions encoding consenter metadata differently; a node with a stale view producing metadata from a previous leader rotation; replayed or cross-proposal signature reuse; message corruption.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- identity in signature header does not match expected identit
- consenter options type mismatch
- failed evaluating policy on signed data during check policy
- Failed evaluating policy on signed data during check policy
- failed to unmarshal BFT metadata configuration
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/f4b49dfd4444db14.
Report an issue: GitHub.