hashicorp/nomad · error

nil config passed

Error message

nil config passed

What it means

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.

Source

Thrown at helper/pluginutils/loader/init.go:28

	"os/exec"
	"path/filepath"
	"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 {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Construct and pass a non-nil *PluginLoaderConfig to NewPluginLoader.
  2. If the config comes from a function, check it for nil before calling NewPluginLoader and handle the upstream failure there.
  3. Check earlier error returns that caused the config to remain nil.

Example fix

// before
loader, err := NewPluginLoader(nil)

// after
cfg := &PluginLoaderConfig{
    Logger:          hclog.NewNullLogger(),
    PluginDir:       "/opt/plugins",
    Configs:         []*PluginConfig{...},
    InternalPlugins: map[string]*InternalPluginConfig{...},
}
loader, err := NewPluginLoader(cfg)
Defensive patterns

Strategy: validation

Validate before calling

if cfg == nil {
    return fmt.Errorf("plugin loader config must be provided")
}
loader, err := NewPluginLoader(cfg)

Type guard

func hasPluginLoaderConfig(cfg *PluginLoaderConfig) bool { return cfg != nil }

Try / catch

loader, err := NewPluginLoader(cfg)
if err != nil {
    if strings.Contains(err.Error(), "nil config passed") {
        return fmt.Errorf("misconfigured bootstrap: loader config missing: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling NewPluginLoader(nil), or passing a variable of type *PluginLoaderConfig that was never assigned (its zero value is nil).

Common situations: 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.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/9cc9e4785df7e557. Report an issue: GitHub.