hashicorp/nomad · error
nil logger passed
Error message
nil logger passed
What it means
validateConfig requires PluginLoaderConfig.Logger to be set because the loader needs a logger for plugin lifecycle events (scanning, fingerprinting, shutdown). When config is non-nil but Logger is nil, this error is appended to a multierror and returned to NewPluginLoader.
Source
Thrown at helper/pluginutils/loader/init.go:30
"sort"
multierror "github.com/hashicorp/go-multierror"
plugin "github.com/hashicorp/go-plugin"
version "github.com/hashicorp/go-version"
"github.com/hashicorp/nomad/helper/pluginutils/hclspecutils"
"github.com/hashicorp/nomad/helper/pluginutils/hclutils"
"github.com/hashicorp/nomad/nomad/structs/config"
"github.com/hashicorp/nomad/plugins/base"
"github.com/zclconf/go-cty/cty/msgpack"
)
// validateConfig returns whether or not the configuration is valid
func validateConfig(config *PluginLoaderConfig) error {
var mErr multierror.Error
if config == nil {
return fmt.Errorf("nil config passed")
} else if config.Logger == nil {
_ = multierror.Append(&mErr, fmt.Errorf("nil logger passed"))
}
// Validate that all plugins have a binary name
for _, c := range config.Configs {
if c.Name == "" {
_ = multierror.Append(&mErr, fmt.Errorf("plugin config passed without binary name"))
}
}
// Validate internal plugins
for k, config := range config.InternalPlugins {
// Validate config
if config == nil {
_ = multierror.Append(&mErr, fmt.Errorf("nil config passed for internal plugin %s", k))
continue
} else if config.Factory == nil {
_ = multierror.Append(&mErr, fmt.Errorf("nil factory passed for internal plugin %s", k))
continueView on GitHub (pinned to 482b49bf1a)
Solutions
- Set Logger on the config, e.g. hclog.New(&hclog.LoggerOptions{Level: hclog.Trace}).
- Use hclog.NewNullLogger() if no log output is desired.
- Share an existing application logger so plugin output goes to the same sink.
Example fix
// before
cfg := &PluginLoaderConfig{PluginDir: dir}
// after
cfg := &PluginLoaderConfig{
PluginDir: dir,
Logger: hclog.New(&hclog.LoggerOptions{Name: "plugins", Level: hclog.Info}),
} Defensive patterns
Strategy: validation
Validate before calling
if cfg == nil || cfg.Logger == nil {
return fmt.Errorf("plugin loader config requires a logger")
}
loader, err := NewPluginLoader(cfg) Type guard
func hasLogger(cfg *PluginLoaderConfig) bool { return cfg != nil && cfg.Logger != nil } Try / catch
loader, err := NewPluginLoader(cfg)
if err != nil {
if strings.Contains(err.Error(), "nil logger passed") {
cfg.Logger = hclog.NewNullLogger()
loader, err = NewPluginLoader(cfg)
}
return err
} Prevention
- Centralize loader-config construction in one helper that always sets Logger.
- Default to hclog.NewNullLogger() in tests instead of leaving the field unset.
- Consider a NewPluginLoaderConfig() builder that assigns a default logger.
When it happens
Trigger: Passing a &PluginLoaderConfig{...} struct literal that omits the Logger field, or explicitly setting Logger: nil.
Common situations: Struct literal construction where only some fields are filled; a logger initialized lazily after NewPluginLoader is called; test code that assumes a default logger exists.
Related errors
- nil config passed
- plugin config passed without binary name
- timeout cannot be negative
- Interval cannot be less than %v (got %v)
- Nomad can only make %v attempts in %v with initial delay %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/b4aa7c31c1bb052c.
Report an issue: GitHub.