hyperledger/fabric · error
invalid BFT metadata configuration
Error message
invalid BFT metadata configuration
What it means
Returned when the BFT metadata unmarshals as smartbft.Options but util.ConfigFromMetadataOptions fails to derive a valid consensus configuration from it. The metadata is structurally a valid protobuf but semantically invalid (e.g. bad batch settings, invalid timeouts, or empty leader-related options).
Source
Thrown at orderer/common/msgprocessor/maintenancefilter.go:145
if nextOrdererConfig.ConsensusState() == orderer.ConsensusType_STATE_NORMAL {
return errors.Errorf("attempted to change consensus type from %s to %s, but next config ConsensusType.State is not in maintenance mode",
ordererConfig.ConsensusType(), nextOrdererConfig.ConsensusType())
}
if !mf.permittedTargetConsensusTypes[nextOrdererConfig.ConsensusType()] {
return errors.Errorf("attempted to change consensus type from %s to %s, transition not supported",
ordererConfig.ConsensusType(), nextOrdererConfig.ConsensusType())
}
if nextOrdererConfig.ConsensusType() == "BFT" {
updatedMetadata := &smartbft.Options{}
if err := proto.Unmarshal(nextOrdererConfig.ConsensusMetadata(), updatedMetadata); err != nil {
return errors.Wrap(err, "failed to unmarshal BFT metadata configuration")
}
_, err := util.ConfigFromMetadataOptions(1, updatedMetadata)
if err != nil {
return errors.New("invalid BFT metadata configuration")
}
err = validateBFTConsenterMapping(ordererConfig, nextOrdererConfig)
if err != nil {
return errors.Wrap(err, "invalid BFT consenter mapping configuration")
}
}
logger.Infof("[channel: %s] consensus-type migration: about to change from %s to %s",
mf.support.ChannelID(), ordererConfig.ConsensusType(), nextOrdererConfig.ConsensusType())
}
if nextOrdererConfig.ConsensusState() != ordererConfig.ConsensusState() {
logger.Infof("[channel: %s] maintenance mode: ConsensusType.State about to change from %s to %s",
mf.support.ChannelID(), ordererConfig.ConsensusState(), nextOrdererConfig.ConsensusState())
}
return nilView on GitHub (pinned to 2736b63f8f)
Solutions
- Fix the smartbft.Options values so ConfigFromMetadataOptions can build a valid config (positive batch sizes, valid timeouts)
- Start from a known-good BFT metadata generated by configtxgen/configtxlator for your Fabric version
- Check orderer local config examples for the version you are migrating to and mirror the option values
Example fix
// before: invalid option "RequestBatchMaxCount": 0 // after: valid option "RequestBatchMaxCount": 100
Defensive patterns
Strategy: validation
Validate before calling
opts := &smartbft.Options{}
if err := proto.Unmarshal(metadata, opts); err != nil { return err }
if _, err := util.ConfigFromMetadataOptions(1, opts); err != nil {
return fmt.Errorf("BFT options semantically invalid: %w", err)
} Prevention
- Start BFT metadata from a known-good template for your Fabric version
- Use positive batch sizes and valid timeout units in smartbft.Options
- Test the update on a disposable channel/network before applying to production
When it happens
Trigger: A maintenance-mode migration to BFT where the smartbft.Options in ConsensusMetadata contain values that ConfigFromMetadataOptions cannot convert into a valid localconfig consensus config (invalid numeric or duration fields, out-of-range options).
Common situations: Administrators crafting BFT metadata by hand with wrong units for timeouts, zero/negative batch sizes, or options copied from an incompatible Fabric version.
Related errors
- failed to unmarshal BFT metadata configuration
- invalid BFT consenter mapping configuration
- unexpected envelope type %s
- empty Config
- empty channel group
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/82191f573d8ae22b.
Report an issue: GitHub.