hyperledger/fabric · error
attempted to change consensus type from %s to %s, but curren
Error message
attempted to change consensus type from %s to %s, but current config ConsensusType.State is not in maintenance mode
What it means
inspect rejects a change of ConsensusType.Type when the current config's ConsensusType.State is STATE_NORMAL. The consensus type may only be changed while the channel is in maintenance mode, so the update is rejected until the channel has first entered STATE_MAINTENANCE.
Source
Thrown at orderer/common/msgprocessor/maintenancefilter.go:124
if ordererConfig.ConsensusState() != nextOrdererConfig.ConsensusState() {
if err1Change := mf.ensureConsensusTypeChangeOnly(configEnvelope); err1Change != nil {
return err1Change
}
if ordererConfig.ConsensusType() != nextOrdererConfig.ConsensusType() {
return errors.Errorf("attempted to change ConsensusType.Type from %s to %s, but ConsensusType.State is changing from %s to %s",
ordererConfig.ConsensusType(), nextOrdererConfig.ConsensusType(), ordererConfig.ConsensusState(), nextOrdererConfig.ConsensusState())
}
if !bytes.Equal(nextOrdererConfig.ConsensusMetadata(), ordererConfig.ConsensusMetadata()) {
return errors.Errorf("attempted to change ConsensusType.Metadata, but ConsensusType.State is changing from %s to %s",
ordererConfig.ConsensusState(), nextOrdererConfig.ConsensusState())
}
}
// ConsensusType.Type can only change in maintenance-mode, and only within the set of permitted types.
// Note: only etcdraft to BFT transitions are supported.
if ordererConfig.ConsensusType() != nextOrdererConfig.ConsensusType() {
if ordererConfig.ConsensusState() == orderer.ConsensusType_STATE_NORMAL {
return errors.Errorf("attempted to change consensus type from %s to %s, but current config ConsensusType.State is not in maintenance mode",
ordererConfig.ConsensusType(), nextOrdererConfig.ConsensusType())
}
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")
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- First submit a config update setting ConsensusType.State to STATE_MAINTENANCE (type unchanged)
- Then change ConsensusType.Type to a permitted target (BFT) while in maintenance
- Finally exit maintenance with a third update setting State to STATE_NORMAL
- Check current state with `osnadmin channel list`/configtxlator before attempting the type change
Example fix
// before: type change attempted from NORMAL
{"type": "BFT", "state": "STATE_NORMAL"}
// after: enter maintenance first
// update 1: {"type": "etcdraft", "state": "STATE_MAINTENANCE"}
// update 2: {"type": "BFT", "state": "STATE_MAINTENANCE"} Defensive patterns
Strategy: validation
Validate before calling
cur, _ := support.OrdererConfig()
if cur.ConsensusType() != next.ConsensusType() && cur.ConsensusState() == orderer.ConsensusType_STATE_NORMAL {
return errors.New("enter STATE_MAINTENANCE before changing consensus type")
} Prevention
- Check current consensus state before every type-change submission
- Always execute the maintenance entry step first
- Use configtxlator to read the live ConsensusType value to confirm state
- Automate the 4-step migration sequence instead of ad-hoc updates
When it happens
Trigger: Submitting a config update changing the orderer consensus type (e.g. etcdraft to BFT) while current ConsensusType.State is STATE_NORMAL.
Common situations: Skipping the maintenance-mode entry step of the raft-to-BFT migration procedure; operator assumes type can be changed directly; stale channel state assumption after another admin reverted to NORMAL.
Related errors
- config transaction inspection failed
- next config attempted to change ConsensusType.State to %s, b
- attempted to change ConsensusType.Type from %s to %s, but Co
- updated config does not include a config update
- failed to parse config
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/a73866b7e8885cd6.
Report an issue: GitHub.