hyperledger/fabric · error

next config attempted to change ConsensusType.Type from %s t

Error message

next config attempted to change ConsensusType.Type from %s to %s, but capability is disabled

What it means

inspect rejects a config update that changes orderer ConsensusType.Type while the ConsensusTypeMigration capability is disabled. The consensus type (e.g. etcdraft, BFT) is immutable on channels lacking the migration capability.

Source

Thrown at orderer/common/msgprocessor/maintenancefilter.go:99

		return errors.Errorf("updated config does not include a config update")
	}

	bundle, err := channelconfig.NewBundle(mf.support.ChannelID(), configEnvelope.Config, mf.bccsp)
	if err != nil {
		return errors.Wrap(err, "failed to parse config")
	}

	nextOrdererConfig, ok := bundle.OrdererConfig()
	if !ok {
		return errors.New("next config is missing orderer group")
	}

	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())
		}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Enable the ConsensusTypeMigration capability first in its own config update
  2. Then enter STATE_MAINTENANCE, change the type, and exit maintenance in separate sequential updates
  3. Confirm the current type matches expectation before submitting (don't resend an old update after capability enablement changed type)
Defensive patterns

Strategy: validation

Validate before calling

oc, _ := support.OrdererConfig()
if !oc.Capabilities().ConsensusTypeMigration() && nextType != oc.ConsensusType() {
	return errors.New("cannot change consensus type: migration capability disabled")
}

Prevention

When it happens

Trigger: Submitting a config update that changes the Orderer group's ConsensusType.Type (e.g. etcdraft to BFT) while ConsensusTypeMigration capability is not enabled on the channel.

Common situations: Attempting a consensus-type change on a channel created with pre-migration capabilities; mixing the capability enablement and type change into one update instead of separate steps.

Related errors


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