hyperledger/fabric · error
config transaction inspection failed
Error message
config transaction inspection failed
What it means
MaintenanceFilter.Apply wraps any error returned by mf.inspect() with "config transaction inspection failed". It means the envelope parsed correctly, but the proposed next orderer config violated one of the consensus-type migration (maintenance mode) transition rules. The transaction is rejected and the wrapped inner error names the specific rule broken.
Source
Thrown at orderer/common/msgprocessor/maintenancefilter.go:71
// Apply applies the maintenance filter on a CONFIG tx.
func (mf *MaintenanceFilter) Apply(message *cb.Envelope) error {
ordererConf, ok := mf.support.OrdererConfig()
if !ok {
logger.Panic("Programming error: orderer config not found")
}
configEnvelope := &cb.ConfigEnvelope{}
chanHdr, err := protoutil.UnmarshalEnvelopeOfType(message, cb.HeaderType_CONFIG, configEnvelope)
if err != nil {
return errors.Wrap(err, "envelope unmarshalling failed")
}
logger.Debugw("Going to inspect maintenance mode transition rules",
"ConsensusState", ordererConf.ConsensusState(), "channel", chanHdr.ChannelId)
err = mf.inspect(configEnvelope, ordererConf)
if err != nil {
return errors.Wrap(err, "config transaction inspection failed")
}
return nil
}
// inspect checks whether the next orderer config, extracted from the incoming configEnvelope, respects the
// transition rules of consensus-type migration using maintenance-mode.
func (mf *MaintenanceFilter) inspect(configEnvelope *cb.ConfigEnvelope, ordererConfig channelconfig.Orderer) error {
if configEnvelope.LastUpdate == nil {
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()View on GitHub (pinned to 2736b63f8f)
Solutions
- Read the wrapped inner error (errors.Cause) to identify the exact violated rule
- Follow the correct migration sequence: enable V2_0/V3 capabilities, enter STATE_MAINTENANCE, change type, exit to STATE_NORMAL, in separate config updates
- Ensure only the ConsensusType value in the Orderer group changes when transitioning state (see ensureConsensusTypeChangeOnly)
- Enable ConsensusTypeMigration in the channel capabilities if migration is intended
Defensive patterns
Strategy: validation
Validate before calling
oc, ok := support.OrdererConfig()
if !ok { panic("no orderer config") }
if !oc.Capabilities().ConsensusTypeMigration() { return errors.New("migration capability not enabled") }
if oc.ConsensusState() != orderer.ConsensusType_STATE_MAINTENANCE && changingType { return errors.New("not in maintenance mode") } Try / catch
if err := filter.Apply(env); err != nil {
if strings.Contains(err.Error(), "config transaction inspection failed") {
cause := errors.Cause(err)
log.Errorf("migration rule violated: %v", cause)
return err
}
} Prevention
- Follow the documented multi-step migration sequence; never combine steps
- Run each proposed config through configtxlator/local inspection before submission
- Enable migration capabilities before any state transition
- Keep one logical change per config update
When it happens
Trigger: Submitting a channel config update that touches orderer.ConsensusType or ConsensusState while it violates migration rules: LastUpdate nil, unparsable config, missing orderer group, capability disabled, changing type/metadata along with state, type change outside maintenance mode, or unsupported target type.
Common situations: Operators following outdated etcdraft-to-BFT migration docs; changing consensus type without first entering STATE_MAINTENANCE; bundling other config changes in the same update as a state transition; ConsensusTypeMigration capability not enabled in the channel.
Related errors
- attempted to change ConsensusType.Type from %s to %s, but Co
- 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/d869ce5d43467fe7.
Report an issue: GitHub.