hyperledger/fabric · error

consenter metadata in OrdererBlockMetadata doesn't match…

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.

Solutions

  1. Reject the proposal and let the BFT layer force a view change / new proposal from a healthy leader.
  2. Ensure all ordering nodes run the same Fabric version so ProposalToBlock encoding is uniform.
  3. Inspect network/TLS integrity between orderers if corruption recurs (packet-level issues, proxies).
  4. 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

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


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

Appendix: 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)