{"record":{"id":"d869ce5d43467fe7","repo":"hyperledger/fabric","slug":"config-transaction-inspection-failed","errorCode":null,"errorMessage":"config transaction inspection failed","messagePattern":"config transaction inspection failed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/msgprocessor/maintenancefilter.go","lineNumber":71,"sourceCode":"\n// Apply applies the maintenance filter on a CONFIG tx.\nfunc (mf *MaintenanceFilter) Apply(message *cb.Envelope) error {\n\tordererConf, ok := mf.support.OrdererConfig()\n\tif !ok {\n\t\tlogger.Panic(\"Programming error: orderer config not found\")\n\t}\n\n\tconfigEnvelope := &cb.ConfigEnvelope{}\n\tchanHdr, err := protoutil.UnmarshalEnvelopeOfType(message, cb.HeaderType_CONFIG, configEnvelope)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"envelope unmarshalling failed\")\n\t}\n\n\tlogger.Debugw(\"Going to inspect maintenance mode transition rules\",\n\t\t\"ConsensusState\", ordererConf.ConsensusState(), \"channel\", chanHdr.ChannelId)\n\terr = mf.inspect(configEnvelope, ordererConf)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"config transaction inspection failed\")\n\t}\n\n\treturn nil\n}\n\n// inspect checks whether the next orderer config, extracted from the incoming configEnvelope, respects the\n// transition rules of consensus-type migration using maintenance-mode.\nfunc (mf *MaintenanceFilter) inspect(configEnvelope *cb.ConfigEnvelope, ordererConfig channelconfig.Orderer) error {\n\tif configEnvelope.LastUpdate == nil {\n\t\treturn errors.Errorf(\"updated config does not include a config update\")\n\t}\n\n\tbundle, err := channelconfig.NewBundle(mf.support.ChannelID(), configEnvelope.Config, mf.bccsp)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to parse config\")\n\t}\n\n\tnextOrdererConfig, ok := bundle.OrdererConfig()","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/msgprocessor/maintenancefilter.go#L53-L89","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"oc, ok := support.OrdererConfig()\nif !ok { panic(\"no orderer config\") }\nif !oc.Capabilities().ConsensusTypeMigration() { return errors.New(\"migration capability not enabled\") }\nif oc.ConsensusState() != orderer.ConsensusType_STATE_MAINTENANCE && changingType { return errors.New(\"not in maintenance mode\") }","typeGuard":null,"tryCatchPattern":"if err := filter.Apply(env); err != nil {\n\tif strings.Contains(err.Error(), \"config transaction inspection failed\") {\n\t\tcause := errors.Cause(err)\n\t\tlog.Errorf(\"migration rule violated: %v\", cause)\n\t\treturn err\n\t}\n}","preventionTips":["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"],"tags":["ordering","consensus-migration","config-update","maintenance-mode"],"backgroundTag":"consensus-type-migration-rule-violation","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}