hashicorp/nomad · error

plugin config passed without binary name

Error message

plugin config passed without binary name

What it means

Every external plugin entry in config.Configs must have a Name identifying the plugin binary. validateConfig iterates the slice and appends this error to a multierror for each entry with an empty Name, because the loader cannot match scanned binaries to configs without it.

Source

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

	"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))
			continue
		}
	}

	return mErr.ErrorOrNil()
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set Name on each PluginConfig to the plugin binary's base name (e.g. "nomad-device-nvidia").
  2. Add a startup-time check that filters or rejects config entries with empty names before building the loader config.
  3. Fix the upstream config source (file/env/flags) so the name is always provided.

Example fix

// before
configs := []*PluginConfig{{Config: map[string]interface{}{"foo": "bar"}}}

// after
configs := []*PluginConfig{{Name: "nomad-driver-docker", Config: map[string]interface{}{"foo": "bar"}}}
Defensive patterns

Strategy: validation

Validate before calling

for i, c := range cfg.Configs {
    if c.Name == "" {
        return fmt.Errorf("configs[%d]: missing plugin binary name", i)
    }
}
loader, err := NewPluginLoader(cfg)

Type guard

func validPluginConfigs(cfgs []*PluginConfig) bool {
    for _, c := range cfgs {
        if c == nil || c.Name == "" {
            return false
        }
    }
    return true
}

Try / catch

loader, err := NewPluginLoader(cfg)
if err != nil {
    if strings.Contains(err.Error(), "without binary name") {
        return fmt.Errorf("plugin config incomplete: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Appending &PluginConfig{} or &PluginConfig{Config: ...} to Configs without setting Name; building configs in a loop where the name variable was empty.

Common situations: Plugin config assembled from environment or CLI flags where the plugin-name flag was missing; YAML/JSON config decoding into PluginConfig where the name key was absent; copy-paste of a config entry with the name removed.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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