hyperledger/fabric · error
failed to unmarshal consensus metadata
Error message
failed to unmarshal consensus metadata
What it means
createSmartBftConfig reads the Orderer config group's consensus metadata and unmarshals it into smartbft.Options. If the metadata bytes are not a valid protobuf encoding of the expected options message, proto.Unmarshal fails and the error is wrapped with this message.
Source
Thrown at orderer/consensus/smartbft/util.go:457
}
if len(w.work) == 0 {
panic("work is not defined")
}
for i, datum := range w.work {
if i%w.workerNum != w.id {
continue
}
w.f(datum)
}
}
func createSmartBftConfig(ordererConfig channelconfig.Orderer) (*smartbft.Options, error) {
configOptions := &smartbft.Options{}
if err := proto.Unmarshal(ordererConfig.ConsensusMetadata(), configOptions); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal consensus metadata")
}
batchSize := ordererConfig.BatchSize()
configOptions.RequestBatchMaxCount = uint64(batchSize.MaxMessageCount)
configOptions.RequestBatchMaxBytes = uint64(batchSize.AbsoluteMaxBytes)
return configOptions, nil
}
// ledgerInfoAdapter translates from blocksprovider.LedgerInfo in to calls to consensus.ConsenterSupport.
type ledgerInfoAdapter struct {
support consensus.ConsenterSupport
}
func (a *ledgerInfoAdapter) LedgerHeight() (uint64, error) {
return a.support.Height(), nil
}
func (a *ledgerInfoAdapter) GetCurrentBlockHash() ([]byte, error) {
return nil, errors.New("not implemented: never used in orderer")View on GitHub (pinned to 2736b63f8f)
Solutions
- Regenerate the config block with correct BFT consensus metadata built by configtxgen/configtxlator
- Use configtxlator to update the consensus_metadata field with a properly encoded smartbft proto instead of hand editing
- Re-commit a config update that sets valid SmartBFT options (window size, batch timeout, etc.)
Defensive patterns
Strategy: validation
Validate before calling
md := ordererConfig.ConsensusMetadata()
opts := &smartbft.Options{}
if err := proto.Unmarshal(md, opts); err != nil {
return fmt.Errorf("invalid BFT consensus metadata: %w", err)
} Type guard
func hasValidBFTMetadata(md []byte) bool {
o := &smartbft.Options{}
return proto.Unmarshal(md, o) == nil
} Try / catch
if _, err := createSmartBftConfig(ordererConfig); err != nil {
if strings.Contains(err.Error(), "failed to unmarshal consensus metadata") {
// regenerate config block via configtxgen/configtxlator
}
} Prevention
- Never hand-edit config block metadata bytes
- Use configtxlator to modify consensus_metadata
- Regenerate genesis blocks after changing consensus settings
When it happens
Trigger: A config block whose Orderer/ConsensusType metadata is empty, truncated, or encoded for a different consensus type (e.g. etcdraft metadata) being processed by HandleChain / configBlockToBFTConfig.
Common situations: Committing a channel config update with wrong or missing consensus metadata; hand-editing config blocks; migrating a channel to BFT without populating BFT options metadata.
Related errors
- failed to unmarshal BFT metadata configuration
- envelope to config update unmarshalling error
- failed to marshal request envelope: proto: Marshal called wi
- invalid consensus type property in config: %v
- invalid options encoded in consensus metadata: %v
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/922d082b229a7298.
Report an issue: GitHub.