hyperledger/fabric · error
attempted to change ConsensusType.Type from %s to %s, but Co
Error message
attempted to change ConsensusType.Type from %s to %s, but ConsensusType.State is changing from %s to %s
What it means
inspect rejects a config update that changes both ConsensusType.Type and ConsensusType.State at once. Maintenance-mode transitions require the state change to be accompanied only by the ConsensusType value change (checked by ensureConsensusTypeChangeOnly) — changing the type in the same update as the state is forbidden, so entry/exit from maintenance and the type swap must be separate config updates.
Source
Thrown at orderer/common/msgprocessor/maintenancefilter.go:111
if !ordererConfig.Capabilities().ConsensusTypeMigration() {
if nextState := nextOrdererConfig.ConsensusState(); nextState != orderer.ConsensusType_STATE_NORMAL {
return errors.Errorf("next config attempted to change ConsensusType.State to %s, but capability is disabled", nextState)
}
if ordererConfig.ConsensusType() != nextOrdererConfig.ConsensusType() {
return errors.Errorf("next config attempted to change ConsensusType.Type from %s to %s, but capability is disabled",
ordererConfig.ConsensusType(), nextOrdererConfig.ConsensusType())
}
return nil
}
// Entry to- and exit from- maintenance-mode should not be accompanied by any other change.
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())View on GitHub (pinned to 2736b63f8f)
Solutions
- Split into sequential updates: (1) enter STATE_MAINTENANCE with type unchanged, (2) change ConsensusType.Type while staying in maintenance, (3) exit to STATE_NORMAL
- When entering/exiting maintenance, ensure the type field in the update equals the current type
- Generate each step's update by diffing configtxlator output of consecutive states
Example fix
// before: one update changing both
"state": "STATE_MAINTENANCE", "type": "BFT" // from etcdraft/NORMAL
// after: two updates
// step 1: {"state": "STATE_MAINTENANCE", "type": "etcdraft"}
// step 2: {"state": "STATE_MAINTENANCE", "type": "BFT"} Defensive patterns
Strategy: validation
Validate before calling
stateChanging := cur.ConsensusState() != next.ConsensusState()
typeChanging := cur.ConsensusType() != next.ConsensusType()
if stateChanging && typeChanging {
return errors.New("split into separate updates: state transition and type change cannot be combined")
} Prevention
- One dimension (state OR type) per config update
- Generate each step's update by diffing consecutive configtxlator outputs
- Follow the official raft-to-BFT migration checklist
When it happens
Trigger: A single config update whose Orderer-group write set changes both ConsensusType.Type and ConsensusType.State (e.g. etcdraft/NORMAL to BFT/MAINTENANCE in one shot).
Common situations: Operator tries to shortcut the raft-to-BFT migration by combining steps; scripted update generated from an incorrect diff of current vs final config.
Related errors
- config transaction inspection failed
- next config attempted to change ConsensusType.State to %s, b
- attempted to change ConsensusType.Metadata, but ConsensusTyp
- attempted to change consensus type from %s to %s, but curren
- updated config does not include a config update
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/1bacf5903bd937e9.
Report an issue: GitHub.