{"record":{"id":"7f4abbae38eb6c92","repo":"hyperledger/fabric","slug":"error-authorizing-update-s","errorCode":null,"errorMessage":"error authorizing update: %s","messagePattern":"error authorizing update: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/configtx/validator.go","lineNumber":144,"sourceCode":"\t\tconfigProto: config,\n\t}, nil\n}\n\n// ProposeConfigUpdate takes in an Envelope of type CONFIG_UPDATE and produces a\n// ConfigEnvelope to be used as the Envelope Payload Data of a CONFIG message\nfunc (vi *ValidatorImpl) ProposeConfigUpdate(configtx *cb.Envelope) (*cb.ConfigEnvelope, error) {\n\treturn vi.proposeConfigUpdate(configtx)\n}\n\nfunc (vi *ValidatorImpl) proposeConfigUpdate(configtx *cb.Envelope) (*cb.ConfigEnvelope, error) {\n\tconfigUpdateEnv, err := protoutil.EnvelopeToConfigUpdate(configtx)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error converting envelope to config update: %s\", err)\n\t}\n\n\tconfigMap, err := vi.authorizeUpdate(configUpdateEnv)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error authorizing update: %s\", err)\n\t}\n\n\tchannelGroup, err := configMapToConfig(configMap, vi.namespace)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"could not turn configMap back to channelGroup: %s\", err)\n\t}\n\n\treturn &cb.ConfigEnvelope{\n\t\tConfig: &cb.Config{\n\t\t\tSequence:     vi.sequence + 1,\n\t\t\tChannelGroup: channelGroup,\n\t\t},\n\t\tLastUpdate: configtx,\n\t}, nil\n}\n\n// Validate simulates applying a ConfigEnvelope to become the new config\nfunc (vi *ValidatorImpl) Validate(configEnv *cb.ConfigEnvelope) error {","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/configtx/validator.go#L126-L162","documentation":"Returned by proposeConfigUpdate when vi.authorizeUpdate rejects the config update after it was successfully converted to a ConfigUpdateEnvelope. Authorization validates the update against current channel config: signature/policy satisfaction, namespaces, read/write sets, and value validation. The wrapped cause names the exact policy or validation rule that failed.","triggerScenarios":"ProposeConfigUpdate called with an update whose signatures don't satisfy the channel mod policy; modifying a group/element without sufficient admin rights; read_set not matching the current config (stale last_sequence); invalid version increments or values rejected by a config value validator.","commonSituations":"Updating channel config signed by an org that isn't in the application/consortium admin policy; not collecting the required number of org signatures (e.g., MAJORITY Endorsement policy unmet); rebasing an old config update on a channel whose sequence has advanced; wrong channel ID inside the ConfigUpdate.","solutions":["Check the wrapped cause: collect and attach signatures from all orgs required by the relevant mod_policy.","Regenerate the update from the latest channel config (fetch current config, apply changes, recompute read/write sets) so read_set matches current sequence.","Use configtxlator to decode current config, edit, and re-encode rather than hand-crafting the update.","Confirm the signer(s) are admins per the channel/Application/Organization mod_policy."],"exampleFix":"// before\nenv, _ := buildUpdate(oldConfig, changes) // stale, single signature\norderer.ProposeConfigUpdate(env)\n// after\nlatest := fetchLatestConfig(orderer)\nenv := buildUpdate(latest, changes)\nenv = collectSignatures(env, requiredAdminOrgs) // satisfy mod_policy\norderer.ProposeConfigUpdate(env)","handlingStrategy":"validation","validationCode":"// pre-flight: verify signatures satisfy the mod policy before proposing\nfor _, s := range cue.Signatures {\n    if !isChannelAdmin(s, channelConfig) { return fmt.Errorf(\"missing admin signature from required org\") }\n}\nif cue.ConfigUpdate.LastSequence != currentConfig.Sequence { return fmt.Errorf(\"stale update: rebuild from latest config\") }","typeGuard":"func hasRequiredSignatures(cue *cb.ConfigUpdateEnvelope, policy Policy) bool { return policy.Evaluate(cue.Signatures) == nil }","tryCatchPattern":"_, err := validator.ProposeConfigUpdate(env)\nif err != nil && strings.Contains(err.Error(), \"error authorizing update\") {\n    // refetch latest config, rebuild update, re-collect required org admin signatures\n}","preventionTips":["Collect signatures from all orgs named by the target mod_policy before submitting","Always rebuild the update from the latest channel config via configtxlator","Verify read_set matches the current config sequence","Confirm signers hold admin MSP roles, not just peer/client roles"],"tags":["hyperledger-fabric","configtx","authorization","policy"],"backgroundTag":"authorization-policy-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"}