{"record":{"id":"b6c67a145b05c61b","repo":"hyperledger/fabric","slug":"config-update-contain-more-then-just-the-s-value","errorCode":null,"errorMessage":"config update contain more then just the %s value in the %s group","messagePattern":"config update contain more then just the (.+?) value in the (.+?) group","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/msgprocessor/maintenancefilter.go","lineNumber":202,"sourceCode":"\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}\n\n\tif ordGroup, ok1 := configUpdate.WriteSet.Groups[channelconfig.OrdererGroupKey]; ok1 {\n\t\tif len(ordGroup.Groups) > 0 {\n\t\t\treturn errors.Errorf(\"config update contains changes to groups within the %s group\",\n\t\t\t\tchannelconfig.OrdererGroupKey)\n\t\t}\n\n\t\tif _, ok2 := ordGroup.Values[channelconfig.ConsensusTypeKey]; !ok2 {\n\t\t\treturn errors.Errorf(\"config update does not contain the %s value\", channelconfig.ConsensusTypeKey)\n\t\t}\n\n\t\tif len(ordGroup.Values) > 1 {\n\t\t\treturn errors.Errorf(\"config update contain more then just the %s value in the %s group\",\n\t\t\t\tchannelconfig.ConsensusTypeKey, channelconfig.OrdererGroupKey)\n\t\t}\n\t} else {\n\t\treturn errors.Errorf(\"update does not contain the %s group\", channelconfig.OrdererGroupKey)\n\t}\n\n\treturn nil\n}\n\nfunc validateBFTConsenterMapping(currentOrdererConfig channelconfig.Orderer, nextOrdererConfig channelconfig.Orderer) error {\n\t// extract raft consenters from consensusTypeValue.metadata\n\traftMetadata := &etcdraft.ConfigMetadata{}\n\tproto.Unmarshal(currentOrdererConfig.ConsensusMetadata(), raftMetadata)\n\traftConsenters := raftMetadata.GetConsenters()\n\n\t// extract bft consenters\n\tbftConsenters := nextOrdererConfig.Consenters()\n","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/msgprocessor/maintenancefilter.go#L184-L220","documentation":"Even when the update contains the ConsensusType value, migration mode requires that it contains ONLY that value in the Orderer group. Any additional Orderer value change (BatchSize, BatchTimeout, capabilities, etc.) makes the update ambiguous/unsafe and is rejected.","triggerScenarios":"ensureConsensusTypeChangeOnly sees ordGroup.Values containing ConsensusTypeKey plus one or more other keys (len(ordGroup.Values) > 1).","commonSituations":"A config delta produced by diffing two configs where the administrator changed both ConsensusType and BatchTimeout before entering maintenance mode; tooling that re-applies a full config instead of a minimal delta.","solutions":["Rebuild the WriteSet so the Orderer group's Values contains exactly one entry: ConsensusType.","Commit unrelated value changes (BatchSize, BatchTimeout, etc.) in a separate update after the channel returns to NORMAL state.","Re-diff with configtxlator against the current maintenance-mode config to isolate the ConsensusType change."],"exampleFix":"// before\nordGroup.Values[\"ConsensusType\"] = ct\nordGroup.Values[\"BatchTimeout\"] = bt // extra value\n// after\nordGroup.Values = map[string]*cb.ConfigValue{\"ConsensusType\": ct}","handlingStrategy":"validation","validationCode":"if ord, ok := update.GetWriteSet().Groups[\"Orderer\"]; ok {\n    if _, hasCT := ord.Values[\"ConsensusType\"]; hasCT && len(ord.Values) > 1 {\n        return errors.New(\"Orderer group may contain only ConsensusType during migration\")\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Postpone BatchSize/BatchTimeout/capabilities edits until after NORMAL state is restored.","Re-diff against the live config so stale values do not sneak into the delta.","Keep the WriteSet minimal: one group, one value."],"tags":["hyperledger-fabric","config-update","consensus-migration"],"backgroundTag":"config-update-rejected","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"}