hyperledger/fabric · error
invalid options encoded in consensus metadata: %v
Error message
invalid options encoded in consensus metadata: %v
What it means
The ConsensusType value unmarshaled fine, but its Metadata must itself unmarshal into a smartbft.Options protobuf. A malformed Metadata blob means the BFT options (ticks, timeouts, leader rotation, etc.) cannot be read, so the update is rejected.
Source
Thrown at orderer/consensus/smartbft/configverifier.go:182
if !proto.Equal(expectedConfigPol, actualPolicy) {
return fmt.Errorf("block validation policy should be a signature policy: %v but it is %v instead", expectedConfigPol, actualPolicy)
}
consensusTypeConfigValue := conf.ChannelGroup.Groups["Orderer"].Values["ConsensusType"]
if consensusTypeConfigValue == nil {
return fmt.Errorf("missing consensus type property in config")
}
consensusTypeValue := &protosorderer.ConsensusType{}
if err := proto.Unmarshal(consensusTypeConfigValue.Value, consensusTypeValue); err != nil {
return fmt.Errorf("invalid consensus type property in config: %v", err)
}
configOptions := &smartbft.Options{}
if err := proto.Unmarshal(consensusTypeValue.Metadata, configOptions); err != nil {
return fmt.Errorf("invalid options encoded in consensus metadata: %v", err)
}
if configOptions.LeaderRotation == smartbft.Options_ROTATION_ON {
return fmt.Errorf("leader rotation must be turned off for this version or be unspecified")
}
return nil
}
func (cbv *ConfigBlockValidator) verifyConfigUpdateMsg(outEnv *common.Envelope, confEnv *common.ConfigEnvelope, chdr *common.ChannelHeader) error {
if confEnv == nil || confEnv.LastUpdate == nil || confEnv.Config == nil {
return errors.New("invalid config envelope")
}
envPayload, err := protoutil.UnmarshalPayload(confEnv.LastUpdate.Payload)
if err != nil {
return err
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Marshal Metadata from a correct &smartbft.Options{} message and store it in ConsensusType.Metadata
- Use configtxgen / the SmartBFT sample config to produce consensusMetadata instead of hand-writing bytes
- Decode the raw metadata with protoc --decode_raw to diagnose the wrong content
Example fix
// before
metadata, _ := proto.Marshal(&etcdraft.Metadata{Consenters: consenters}) // wrong proto type for BFT
// after
metadata, _ := proto.Marshal(&smartbft.Options{DecisionTimeout: 500, LeaderRotation: smartbft.Options_ROTATION_OFF}) Defensive patterns
Strategy: validation
Validate before calling
opts := &smartbft.Options{}
if err := proto.Unmarshal(consensusTypeValue.Metadata, opts); err != nil {
return fmt.Errorf("consensus metadata is not valid smartbft.Options: %w", err)
} Try / catch
if err := verifyMetadata(consensusTypeValue.Metadata); err != nil {
return fmt.Errorf("aborting config submission: %w", err)
} Prevention
- Build BFT metadata only from smartbft.Options / etcdraft consenters marshaled by the matching Fabric version
- Decode existing metadata with protoc --decode_raw before modifying
- Do not copy etcdraft Metadata into BFT channels
When it happens
Trigger: proto.Unmarshal(consensusTypeValue.Metadata, configOptions) fails in checkConsentersMatchPolicy — Metadata bytes are empty-but-non-nil garbage, wrong message type, or corrupted.
Common situations: Consenter metadata assembled by custom tooling using the wrong proto; hand-edited consensus metadata; ordering-node versions writing incompatible Options fields; copying metadata from an etcdraft channel into a BFT channel.
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
- failed to unmarshal BFT metadata configuration
- failed to marshal request envelope: proto: Marshal called wi
- invalid consensus type property in config: %v
- bad payload
- bad metadata
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/e01d4b54341da394.
Report an issue: GitHub.