hyperledger/fabric · error

failed unmarshaling smartbft metadata from block

Error message

failed unmarshaling smartbft metadata from block

What it means

Inside the block's OrdererBlockMetadata, the ConsenterMetadata field must decode into the smartbft ViewMetadata proto. Failure means the SmartBFT view metadata stored in the block is not valid protobuf for the expected message, so the verifier cannot compare it against the proposal metadata.

Source

Thrown at orderer/consensus/smartbft/verifier.go:286

	if block.Metadata == nil || len(block.Metadata.Metadata) < len(cb.BlockMetadataIndex_name) {
		return nil, errors.New("block metadata is either missing or contains too few entries")
	}

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

	// Ensure the view metadata in the block signature and in the proposal are the same

	metadataInBlock := &smartbftprotos.ViewMetadata{}
	if err := proto.Unmarshal(ordererMetadataFromSignature.ConsenterMetadata, metadataInBlock); err != nil {
		return nil, errors.Wrap(err, "failed unmarshaling smartbft metadata from block")
	}

	metadataFromProposal := &smartbftprotos.ViewMetadata{}
	if err := proto.Unmarshal(metadata, metadataFromProposal); err != nil {
		return nil, errors.Wrap(err, "failed unmarshaling smartbft metadata from proposal")
	}

	if !proto.Equal(metadataInBlock, metadataFromProposal) {
		return nil, errors.Errorf(
			"expected metadata in block to be [view_id:%d latest_sequence:%d] but got [view_id:%d latest_sequence:%d]",
			metadataFromProposal.GetViewId(), metadataFromProposal.GetLatestSequence(),
			metadataInBlock.GetViewId(), metadataInBlock.GetLatestSequence(),
		)
	}

	rtc := v.RuntimeConfig.Load().(RuntimeConfig)
	lastConfig := rtc.LastConfigBlock.Header.Number

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure ConsenterMetadata is set to a valid marshaled smartbftprotos.ViewMetadata during block assembly
  2. Align all cluster nodes on the same fabric/smartbft version
  3. Log and inspect the offending ConsenterMetadata bytes to spot truncation or emptiness
  4. Re-propose the block from a node with correct metadata

Example fix

// before
obm.ConsenterMetadata = nil
// after
vm := &smartbftprotos.ViewMetadata{ViewId: seq, LatestSequence: latest}
obm.ConsenterMetadata, _ = proto.Marshal(vm)
Defensive patterns

Strategy: validation

Validate before calling

vm := &smartbftprotos.ViewMetadata{}
if err := proto.Unmarshal(obm.ConsenterMetadata, vm); err != nil {
    return errors.New("ConsenterMetadata is not a valid ViewMetadata")
}

Type guard

func validViewMetadata(b []byte) bool { return proto.Unmarshal(b, &smartbftprotos.ViewMetadata{}) == nil }

Try / catch

if _, err := verifier.VerifyProposal(...); err != nil && strings.Contains(err.Error(), "smartbft metadata from block") {
    logger.Warn("invalid ViewMetadata in block; discarding proposal")
}

Prevention

When it happens

Trigger: proto.Unmarshal(ordererMetadataFromSignature.ConsenterMetadata, metadataInBlock) errors — ConsenterMetadata is empty/garbage, or was produced by a different smartbft proto version.

Common situations: Nodes running mismatched smartbft library versions with different ViewMetadata schemas; consenter metadata overwritten by custom ordering-system code; corrupted proposal bytes; metadata not populated when the block was built.

Related errors


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