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

  1. Regenerate the config block with correct BFT consensus metadata built by configtxgen/configtxlator
  2. Use configtxlator to update the consensus_metadata field with a properly encoded smartbft proto instead of hand editing
  3. 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

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


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