{"record":{"id":"9cc9e4785df7e557","repo":"hashicorp/nomad","slug":"nil-config-passed-9cc9e4","errorCode":null,"errorMessage":"nil config passed","messagePattern":"nil config passed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/pluginutils/loader/init.go","lineNumber":28,"sourceCode":"\t\"os/exec\"\n\t\"path/filepath\"\n\t\"sort\"\n\n\tmultierror \"github.com/hashicorp/go-multierror\"\n\tplugin \"github.com/hashicorp/go-plugin\"\n\tversion \"github.com/hashicorp/go-version\"\n\t\"github.com/hashicorp/nomad/helper/pluginutils/hclspecutils\"\n\t\"github.com/hashicorp/nomad/helper/pluginutils/hclutils\"\n\t\"github.com/hashicorp/nomad/nomad/structs/config\"\n\t\"github.com/hashicorp/nomad/plugins/base\"\n\t\"github.com/zclconf/go-cty/cty/msgpack\"\n)\n\n// validateConfig returns whether or not the configuration is valid\nfunc validateConfig(config *PluginLoaderConfig) error {\n\tvar mErr multierror.Error\n\tif config == nil {\n\t\treturn fmt.Errorf(\"nil config passed\")\n\t} else if config.Logger == nil {\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"nil logger passed\"))\n\t}\n\n\t// Validate that all plugins have a binary name\n\tfor _, c := range config.Configs {\n\t\tif c.Name == \"\" {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"plugin config passed without binary name\"))\n\t\t}\n\t}\n\n\t// Validate internal plugins\n\tfor k, config := range config.InternalPlugins {\n\t\t// Validate config\n\t\tif config == nil {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"nil config passed for internal plugin %s\", k))\n\t\t\tcontinue\n\t\t} else if config.Factory == nil {","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/pluginutils/loader/init.go#L10-L46","documentation":"NewPluginLoader validates its *PluginLoaderConfig before doing any work. If the caller passes a literal nil config pointer, validateConfig returns this error immediately instead of panicking later on field access. It signals that no configuration object was supplied at all, so the loader cannot be constructed.","triggerScenarios":"Calling NewPluginLoader(nil), or passing a variable of type *PluginLoaderConfig that was never assigned (its zero value is nil).","commonSituations":"Declarative var declarations like `var cfg *PluginLoaderConfig` that are populated only conditionally; refactoring where config construction was moved behind a function that now returns nil on an error path; test code that forgot to build a config.","solutions":["Construct and pass a non-nil *PluginLoaderConfig to NewPluginLoader.","If the config comes from a function, check it for nil before calling NewPluginLoader and handle the upstream failure there.","Check earlier error returns that caused the config to remain nil."],"exampleFix":"// before\nloader, err := NewPluginLoader(nil)\n\n// after\ncfg := &PluginLoaderConfig{\n    Logger:          hclog.NewNullLogger(),\n    PluginDir:       \"/opt/plugins\",\n    Configs:         []*PluginConfig{...},\n    InternalPlugins: map[string]*InternalPluginConfig{...},\n}\nloader, err := NewPluginLoader(cfg)","handlingStrategy":"validation","validationCode":"if cfg == nil {\n    return fmt.Errorf(\"plugin loader config must be provided\")\n}\nloader, err := NewPluginLoader(cfg)","typeGuard":"func hasPluginLoaderConfig(cfg *PluginLoaderConfig) bool { return cfg != nil }","tryCatchPattern":"loader, err := NewPluginLoader(cfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"nil config passed\") {\n        return fmt.Errorf(\"misconfigured bootstrap: loader config missing: %w\", err)\n    }\n    return err\n}","preventionTips":["Always build the loader config via a constructor function that never returns nil.","Check the error of any function that produces the config before passing it on.","Avoid `var cfg *PluginLoaderConfig` in favor of immediate struct literal assignment."],"tags":["go","configuration","nil-pointer","validation"],"backgroundTag":"nil-config-passed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}