hyperledger/fabric · error
failed unmarshaling smartbft metadata from proposal
Error message
failed unmarshaling smartbft metadata from proposal
What it means
The ViewMetadata supplied with the proposal (the raw metadata parameter) must itself decode into smartbftprotos.ViewMetadata. If it cannot be unmarshaled, the proposal's metadata is malformed and the verifier wraps the error, mirroring the block-side failure but attributed to the proposal.
Source
Thrown at orderer/consensus/smartbft/verifier.go:291
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
if protoutil.IsConfigBlock(block) {
lastConfig = block.Header.Number
}
// Verify last configView on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the caller passes the marshaled smartbftprotos.ViewMetadata, not other metadata blobs
- Check smartbft library version parity across all consenter nodes
- Marshal metadata explicitly with proto.Marshal on the ViewMetadata message before proposal
- Log the offending metadata bytes to identify the wrong source
Example fix
// before: passing orderer metadata instead of view metadata
err := verifier.VerifyProposal([]byte{...}, ordererMetadataBytes)
// after
viewMetaBytes, _ := proto.Marshal(viewMetadata)
err := verifier.VerifyProposal([]byte{...}, viewMetaBytes) Defensive patterns
Strategy: validation
Validate before calling
pm := &smartbftprotos.ViewMetadata{}
if err := proto.Unmarshal(proposalMetadataBytes, pm); err != nil {
return errors.New("proposal metadata is not a valid ViewMetadata")
} Type guard
func validProposalMetadata(b []byte) bool { return proto.Unmarshal(b, &smartbftprotos.ViewMetadata{}) == nil } Try / catch
if _, err := verifier.VerifyProposal(proposal, metadata); err != nil && strings.Contains(err.Error(), "smartbft metadata from proposal") {
logger.Warn("malformed proposal metadata; verify caller passes marshaled ViewMetadata")
} Prevention
- Pass proto.Marshal(viewMetadata) output as the metadata argument, never other blobs
- Unit-test VerifyProposal calls with known-good metadata bytes
- Keep smartbft library versions in lockstep across the cluster
- Log metadata bytes on failure to confirm the correct source slice
When it happens
Trigger: VerifyProposal is called with a metadata []byte argument that fails proto.Unmarshal into ViewMetadata — e.g. nil/empty bytes, wrong message type, or bytes from a different smartbft version.
Common situations: Caller passing the wrong byte slice (block bytes or orderer metadata instead of view metadata); version mismatch between the leader producing the proposal and the verifier; corrupted proposal received over the network.
Related errors
- failed unmarshaling smartbft metadata from block
- malformed message
- malformed signature format
- failed unmarshaling OrdererBlockMetadata
- error unmarshalling
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/6a7ae5bbc47df551.
Report an issue: GitHub.