hyperledger/fabric · critical

failed unmarshalling OrdererBlockMetadata

Error message

failed unmarshalling OrdererBlockMetadata

What it means

getViewMetadataFromBlock reads the SIGNATURES block metadata, unmarshals it as OrdererBlockMetadata, and on failure wraps the proto error as 'failed unmarshalling OrdererBlockMetadata'. This metadata carries the current SmartBFT view metadata; without it the node cannot determine view/sequence state for the block.

Source

Thrown at orderer/consensus/smartbft/util.go:136

	consensusConfigOptions, err := createSmartBftConfig(oc)
	if err != nil {
		return types.Configuration{}, err
	}

	return util.ConfigFromMetadataOptions(selfID, consensusConfigOptions)
}

func getViewMetadataFromBlock(block *cb.Block) (*smartbftprotos.ViewMetadata, error) {
	if block.Header.Number == 0 {
		// Genesis block has no prior metadata so we just return an un-initialized metadata
		return new(smartbftprotos.ViewMetadata), nil
	}

	signatureMetadata := protoutil.GetMetadataFromBlockOrPanic(block, cb.BlockMetadataIndex_SIGNATURES)
	ordererMD := &cb.OrdererBlockMetadata{}
	if err := proto.Unmarshal(signatureMetadata.Value, ordererMD); err != nil {
		return nil, errors.Wrap(err, "failed unmarshalling OrdererBlockMetadata")
	}

	var viewMetadata smartbftprotos.ViewMetadata
	if err := proto.Unmarshal(ordererMD.ConsenterMetadata, &viewMetadata); err != nil {
		return nil, err
	}

	return &viewMetadata, nil
}

type request struct {
	sigHdr   *cb.SignatureHeader
	envelope *cb.Envelope
	chHdr    *cb.ChannelHeader
}

// RequestInspector inspects incoming requests and validates serialized identity
type RequestInspector struct {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Do not mix block metadata formats; ensure the channel was created/updated for SmartBFT properly (no in-place Raft-to-BFT metadata mixing)
  2. Check ledger integrity; restore the channel from a snapshot if metadata is corrupted
  3. Verify all orderers run compatible Fabric versions producing the same OrdererBlockMetadata proto
  4. Re-create the channel with a fresh genesis block if migration was incorrect
Defensive patterns

Strategy: type-guard

Validate before calling

sigMD := protoutil.GetMetadataFromBlockOrPanic(block, cb.BlockMetadataIndex_SIGNATURES)
md := &cb.OrdererBlockMetadata{}
if proto.Unmarshal(sigMD.Value, md) != nil || md.ConsenterMetadata == nil {
  return errors.New("block lacks valid SmartBFT OrdererBlockMetadata")
}

Type guard

func hasBFTMetadata(block *cb.Block) bool {
  sigMD := protoutil.GetMetadataFromBlockOrPanic(block, cb.BlockMetadataIndex_SIGNATURES)
  md := &cb.OrdererBlockMetadata{}
  return proto.Unmarshal(sigMD.Value, md) == nil && md.ConsenterMetadata != nil
}

Try / catch

vm, err := getViewMetadataFromBlock(block)
if err != nil {
  return fmt.Errorf("cannot build BFT chain from this block's metadata: %w", err)
}

Prevention

When it happens

Trigger: bftSmartConsensusBuild during chain construction or getViewMetadataLastConfigSqnFromBlock when the block's SIGNATURES metadata was not produced by SmartBFT (e.g. blocks from a Raft channel, foreign/edited metadata, or corruption).

Common situations: Switching a channel from Raft to BFT without proper migration so blocks lack OrdererBlockMetadata, manual block editing/corruption, or a version mismatch where the metadata protobuf changed shape.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


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