{"record":{"id":"599fd73bb6b3b13b","repo":"hyperledger/fabric","slug":"envelope-to-config-update-unmarshalling-error","errorCode":null,"errorMessage":"envelope to config update unmarshalling error","messagePattern":"envelope to config update unmarshalling error","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/msgprocessor/maintenancefilter.go","lineNumber":171,"sourceCode":"\n\t\tlogger.Infof(\"[channel: %s] consensus-type migration: about to change from %s to %s\",\n\t\t\tmf.support.ChannelID(), ordererConfig.ConsensusType(), nextOrdererConfig.ConsensusType())\n\t}\n\n\tif nextOrdererConfig.ConsensusState() != ordererConfig.ConsensusState() {\n\t\tlogger.Infof(\"[channel: %s] maintenance mode: ConsensusType.State about to change from %s to %s\",\n\t\t\tmf.support.ChannelID(), ordererConfig.ConsensusState(), nextOrdererConfig.ConsensusState())\n\t}\n\n\treturn nil\n}\n\n// ensureConsensusTypeChangeOnly checks that the only change is the Channel/Orderer group, and within that,\n// only to the ConsensusType value.\nfunc (mf *MaintenanceFilter) ensureConsensusTypeChangeOnly(configEnvelope *cb.ConfigEnvelope) error {\n\tconfigUpdateEnv, err := protoutil.EnvelopeToConfigUpdate(configEnvelope.LastUpdate)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"envelope to config update unmarshalling error\")\n\t}\n\n\tconfigUpdate, err := configtx.UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"config update unmarshalling error\")\n\t}\n\n\tif len(configUpdate.WriteSet.Groups) == 0 {\n\t\treturn errors.New(\"config update contains no changes\")\n\t}\n\n\tif len(configUpdate.WriteSet.Values) > 0 {\n\t\treturn errors.Errorf(\"config update contains changes to values in group %s\", channelconfig.ChannelGroupKey)\n\t}\n\n\tif len(configUpdate.WriteSet.Groups) > 1 {\n\t\treturn errors.New(\"config update contains changes to more than one group\")\n\t}","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/msgprocessor/maintenancefilter.go#L153-L189","documentation":"Wraps a failure when ensureConsensusTypeChangeOnly converts the config update envelope (configEnvelope.LastUpdate) into a ConfigUpdateEnvelope via protoutil.EnvelopeToConfigUpdate. The submitted envelope is not a well-formed config update (wrong payload type, corrupt bytes), so the migration filter cannot inspect it.","triggerScenarios":"Submitting a transaction envelope to the orderer during migration whose payload is not a CONFIG_UPDATE (e.g. a normal data transaction, or a truncated/incorrectly serialized envelope) while it is expected to be the migration update.","commonSituations":"Using configtxlator or the SDK incorrectly and producing an envelope whose inner payload is mis-typed, or sending the config update envelope before it was fully assembled/signed.","solutions":["Rebuild the config update envelope with configtxlator proto_encode of a valid ConfigUpdateEnvelope","Ensure the envelope payload type is cb.HeaderType_CONFIG_UPDATE and the ConfigUpdate bytes serialize correctly","Re-run the compute-update/update pipeline in configtxlator from the two config blocks"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Go: verify the envelope payload is a CONFIG_UPDATE before submitting\npayload := &cb.Payload{}\nif err := proto.Unmarshal(env.Payload, payload); err != nil { return err }\nif payload.Header.Type != int32(cb.HeaderType_CONFIG_UPDATE) {\n    return errors.New(\"envelope payload is not a config update\")\n}","typeGuard":"func isConfigUpdateEnvelope(env *cb.Envelope) bool {\n    p := &cb.Payload{}\n    return proto.Unmarshal(env.Payload, p) == nil && p.Header.GetType() == int32(cb.HeaderType_CONFIG_UPDATE)\n}","tryCatchPattern":null,"preventionTips":["Assemble migration updates only with configtxlator/proto tooling","Check the envelope header type before sending to the orderer","Re-encode envelopes after every edit instead of reusing stale artifacts"],"tags":["hyperledger-fabric","orderer","config-update","protobuf"],"backgroundTag":"protobuf-unmarshal-failed","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"}