{"record":{"id":"2e082b35983765fd","repo":"hyperledger/fabric","slug":"cannot-process-nil-configupdateenvelope","errorCode":null,"errorMessage":"cannot process nil ConfigUpdateEnvelope","messagePattern":"cannot process nil ConfigUpdateEnvelope","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/configtx/update.go","lineNumber":118,"sourceCode":"\t\t}\n\t}\n\treturn nil\n}\n\nfunc verifyFullProposedConfig(writeSet, fullProposedConfig map[string]comparable) error {\n\tfor key := range writeSet {\n\t\tif _, ok := fullProposedConfig[key]; !ok {\n\t\t\treturn errors.Errorf(\"writeset contained key %s which did not appear in proposed config\", key)\n\t\t}\n\t}\n\treturn nil\n}\n\n// authorizeUpdate validates that all modified config has the corresponding modification policies satisfied by the signature set\n// it returns a map of the modified config\nfunc (vi *ValidatorImpl) authorizeUpdate(configUpdateEnv *cb.ConfigUpdateEnvelope) (map[string]comparable, error) {\n\tif configUpdateEnv == nil {\n\t\treturn nil, errors.Errorf(\"cannot process nil ConfigUpdateEnvelope\")\n\t}\n\n\tconfigUpdate, err := UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif configUpdate.ChannelId != vi.channelID {\n\t\treturn nil, errors.Errorf(\"ConfigUpdate for channel '%s' but envelope for channel '%s'\", configUpdate.ChannelId, vi.channelID)\n\t}\n\n\treadSet, err := mapConfig(configUpdate.ReadSet, vi.namespace)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"error mapping ReadSet\")\n\t}\n\terr = vi.verifyReadSet(readSet)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"error validating ReadSet\")","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/configtx/update.go#L100-L136","documentation":"authorizeUpdate was invoked with a nil ConfigUpdateEnvelope. The validator cannot authorize a config update without the envelope that carries the serialized ConfigUpdate and its signatures, so it fails immediately.","triggerScenarios":"Calling proposeConfigUpdate or Validate and passing a nil envelope — e.g. when the enclosing envelope's payload failed to unmarshal earlier, or the caller passes nil directly.","commonSituations":"Submitting an empty/garbage transaction to the orderer that unmarshals to a nil envelope; a bug in calling code that skips envelope construction; transaction filtered to nil upstream then still validated.","solutions":["Ensure a valid ConfigUpdateEnvelope is constructed (marshaled ConfigUpdate bytes plus signatures) before calling proposeConfigUpdate/Validate.","Check the caller that produced the envelope for early unmarshal failures that left it nil.","Guard the call site with a nil check and reject the transaction/proposal before invoking the validator."],"exampleFix":"// before\nnewConfig, err := validator.proposeConfigUpdate(nil)\n// after\nif configEnv == nil {\n    return errors.New(\"no config update envelope provided\")\n}\nnewConfig, err := validator.proposeConfigUpdate(configEnv)","handlingStrategy":"type-guard","validationCode":"// Reject nil envelopes at the boundary before invoking the validator\nfunc validateEnvelope(env *cb.ConfigUpdateEnvelope) error {\n    if env == nil || len(env.GetConfigUpdate()) == 0 {\n        return errors.New(\"empty ConfigUpdateEnvelope\")\n    }\n    return nil\n}","typeGuard":"func isNilEnvelope(env *cb.ConfigUpdateEnvelope) bool {\n    return env == nil || env.GetConfigUpdate() == nil\n}","tryCatchPattern":"if isNilEnvelope(env) {\n    return errors.New(\"config update envelope is nil\")\n}\nif _, err := validator.ProposeConfigUpdate(env, seq); err != nil {\n    return err\n}","preventionTips":["Nil-check envelopes immediately after unmarshal; treat unmarshal errors as fatal, not as nil results.","Never pass through envelopes from failed payload parsing.","Log and reject malformed transactions before validation rather than letting the validator nil-fail."],"tags":["hyperledger-fabric","configtx","nil-envelope"],"backgroundTag":"nil-input","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"}