{"record":{"id":"b404ec20f3dd7a47","repo":"hyperledger/fabric","slug":"maintenance-mode","errorCode":null,"errorMessage":"maintenance mode","messagePattern":"maintenance mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"orderer/common/msgprocessor/msgprocessor.go","lineNumber":36,"sourceCode":"const (\n\t// These should eventually be derived from the channel support once enabled\n\tmsgVersion = int32(0)\n\tepoch      = 0\n)\n\nvar logger = flogging.MustGetLogger(\"orderer.common.msgprocessor\")\n\n// ErrChannelDoesNotExist is returned by the system channel for transactions which\n// are not for the system channel ID and are not attempting to create a new channel\nvar ErrChannelDoesNotExist = errors.New(\"channel does not exist\")\n\n// ErrPermissionDenied is returned by errors which are caused by transactions\n// which are not permitted due to an authorization failure.\nvar ErrPermissionDenied = errors.New(\"permission denied\")\n\n// ErrMaintenanceMode is returned when transactions are rejected because the orderer is in \"maintenance mode\",\n// as defined by ConsensusType.State != NORMAL. This typically happens during consensus-type migration.\nvar ErrMaintenanceMode = errors.New(\"maintenance mode\")\n\n// Classification represents the possible message types for the system.\ntype Classification int\n\nconst (\n\t// NormalMsg is the class of standard (endorser or otherwise non-config) messages.\n\t// Messages of this type should be processed by ProcessNormalMsg.\n\tNormalMsg Classification = iota\n\n\t// ConfigUpdateMsg indicates messages of type CONFIG_UPDATE.\n\t// Messages of this type should be processed by ProcessConfigUpdateMsg.\n\tConfigUpdateMsg\n\n\t// ConfigMsg indicates message of type CONFIG.\n\t// Messages of this type should be processed by ProcessConfigMsg\n\tConfigMsg\n\n\t// UnsupportedMsg indicates a message of type ORDERER_TRANSACTION, which is no longer supported, since support for","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/msgprocessor/msgprocessor.go#L18-L54","documentation":"ErrMaintenanceMode is returned when the orderer is in maintenance mode (channelconfig ConsensusType.State != NORMAL, typically during consensus-type migration) and a normal (non-config) transaction is submitted. It is returned wrapped via errors.WithMessage(\"normal transactions are rejected\") in StandardChannel.ProcessNormalMsg and mapped by ClassifyError to SERVICE_UNAVAILABLE.","triggerScenarios":"Broadcasting an ordinary endorsement transaction to a channel whose consensus type state is MAINTENANCE; only config updates related to the migration are accepted at that time.","commonSituations":"Applications continuing to send transactions while admins perform a Raft-to-BFT migration; forgetting to complete the migration and return the channel to NORMAL state.","solutions":["Pause client transaction submission until the consensus-type migration completes.","Finish the migration steps and submit the config update setting ConsensusType State back to NORMAL.","Verify the channel's consensus state (configtxlator or channel config) before resuming traffic.","Retry the transaction with backoff once the orderer returns SERVICE_UNAVAILABLE→OK."],"exampleFix":"// before\n// client keeps sending txs during migration\n// after\n// wait for ConsensusType.State == NORMAL, then resume send(env)","handlingStrategy":"retry","validationCode":"// check consensus state via fetched channel config\nvar ct orderer.ConsensusType\nproto.Unmarshal(ordererGroup.Values[\"ConsensusType\"].Value, &ct)\nready := ct.State == orderer.ConsensusType_STATE_NORMAL","typeGuard":null,"tryCatchPattern":"err := broadcastClient.Send(env)\nif errors.Is(err, msgprocessor.ErrMaintenanceMode) || statusOf(err) == cb.Status_SERVICE_UNAVAILABLE {\n    // migrate paused traffic; retry with backoff until channel returns to NORMAL\n}","preventionTips":["Coordinate with admins: stop client traffic during consensus-type migration.","Monitor channel config for ConsensusType.State transitions.","Implement retry-with-backoff on SERVICE_UNAVAILABLE responses from the orderer."],"tags":["hyperledger-fabric","maintenance-mode","consensus-migration"],"backgroundTag":"service-unavailable","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"}