{"record":{"id":"42987f995e6e8da6","repo":"hyperledger/fabric","slug":"config-envelope-is-nil","errorCode":null,"errorMessage":"config envelope is nil","messagePattern":"config envelope is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/configtx/validator.go","lineNumber":164,"sourceCode":"\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 {\n\tif configEnv == nil {\n\t\treturn errors.Errorf(\"config envelope is nil\")\n\t}\n\n\tif configEnv.Config == nil {\n\t\treturn errors.Errorf(\"config envelope has nil config\")\n\t}\n\n\tif configEnv.Config.Sequence != vi.sequence+1 {\n\t\treturn errors.Errorf(\"config currently at sequence %d, cannot validate config at sequence %d\", vi.sequence, configEnv.Config.Sequence)\n\t}\n\n\tconfigUpdateEnv, err := protoutil.EnvelopeToConfigUpdate(configEnv.LastUpdate)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tconfigMap, err := vi.authorizeUpdate(configUpdateEnv)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/configtx/validator.go#L146-L182","documentation":"ValidatorImpl.Validate returns this when the caller passes a nil ConfigEnvelope. Validate simulates applying a config envelope, so there is nothing to validate and it fails fast before any field access (avoiding a nil-pointer dereference). It is a simple guard, not a deep validation failure.","triggerScenarios":"Calling Validate(nil), or calling it with the result of a function that returned (nil, err) where the err was ignored.","commonSituations":"Passing an unwrapped nil pointer from config fetch/deserialization code paths; test harnesses constructing envelopes dynamically; storing config envelopes in maps/pointers that were never initialized.","solutions":["Check that the ConfigEnvelope pointer is non-nil before calling Validate.","Fix the upstream producer that returned a nil envelope and swallow/inspect its error.","In Go, guard with if env == nil { return } prior to validation."],"exampleFix":"// before\nvar env *cb.ConfigEnvelope\nvalidator.Validate(env)\n// after\nif env == nil { return errors.New(\"no config envelope to validate\") }\nvalidator.Validate(env)","handlingStrategy":"type-guard","validationCode":"if configEnv == nil { return errors.New(\"config envelope is nil; nothing to validate\") }","typeGuard":"func isNonNilConfigEnvelope(env *cb.ConfigEnvelope) bool { return env != nil }","tryCatchPattern":"if err := validator.Validate(env); err != nil {\n    if strings.Contains(err.Error(), \"config envelope is nil\") {\n        // fix upstream producer that returned a nil envelope\n        return err\n    }\n}","preventionTips":["Always check pointer-nil before calling Validate","Never ignore the error return of functions that produce the envelope (err may accompany nil result)","Initialize envelope variables at declaration where possible"],"tags":["hyperledger-fabric","configtx","nil-pointer","validation"],"backgroundTag":"nil-argument","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"}