hashicorp/nomad · error

unknown plugin with name %q and type %q

Error message

unknown plugin with name %q and type %q

What it means

Dispense looks up a plugin instance by PluginID{Name, PluginType} in the loader's plugins map; if absent it returns this error. It means the named plugin was never registered — it was not found in the plugin dir, its config stanza names a plugin that doesn't exist, or the loader wasn't initialized with it.

Source

Thrown at helper/pluginutils/loader/loader.go:170

	for i, c := range config.Configs {
		if updated, ok := updatedConfig[c.Name]; ok {
			config.Configs[i] = updated
		}
	}

	return l, nil
}

// Dispense returns a plugin instance, loading it either internally or by
// launching an external plugin.
func (l *PluginLoader) Dispense(name, pluginType string, config *base.AgentConfig, logger log.Logger) (PluginInstance, error) {
	id := PluginID{
		Name:       name,
		PluginType: pluginType,
	}
	pinfo, ok := l.plugins[id]
	if !ok {
		return nil, fmt.Errorf("unknown plugin with name %q and type %q", name, pluginType)
	}

	// If the plugin is internal, launch via the factory
	var instance PluginInstance
	if pinfo.factory != nil {
		ctx, cancel := context.WithCancel(context.Background())
		instance = &internalPluginInstance{
			instance:   pinfo.factory(ctx, logger),
			apiVersion: pinfo.apiVersion,
			killFn:     cancel,
		}
	} else {
		var err error
		instance, err = l.dispensePlugin(pinfo.baseInfo.Type, pinfo.apiVersion, pinfo.exePath, pinfo.args, nil, logger)
		if err != nil {
			return nil, fmt.Errorf("failed to launch plugin: %v", err)
		}
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure the plugin stanza's name matches the plugin binary filename in plugin_dir exactly.
  2. Verify the plugin binary exists and is executable in the configured plugin_dir.
  3. Check the pluginType argument matches the type the plugin registers (task driver vs device, etc.).
  4. Restart agent config discovery: confirm the loader init logs list the plugin as discovered.
  5. Install the missing plugin or remove the stanza from the agent config.

Example fix

// before (agent config)
plugin "dockerd" {
  config { ... }   # no such plugin installed
}
// after (correct binary name)
plugin "docker" {
  config { ... }
}
Defensive patterns

Strategy: validation

Validate before calling

// Before writing a plugin stanza, confirm the plugin is discoverable:
ids := []loader.PluginID{} // from loader introspection/logs at startup
func pluginInstalled(name, ptype string, dir string) bool {
    _, err := os.Stat(filepath.Join(dir, name))
    return err == nil
}
if !pluginInstalled("docker", "driver", cfg.PluginDir) {
    return errors.New("plugin stanza references uninstalled plugin")
}

Try / catch

inst, err := l.Dispense(name, ptype, agentCfg, logger)
if err != nil && strings.Contains(err.Error(), "unknown plugin") {
    return fmt.Errorf("plugin %q (%s) not found in %s; install it or fix the stanza", name, ptype, cfg.PluginDir)
}

Prevention

When it happens

Trigger: Calling Dispense (e.g. from validatePluginConfig during agent startup) with a name/pluginType pair that has no entry in l.plugins — typically a `plugin "name" { type = ... }` stanza in the agent config referencing an uninstalled plugin.

Common situations: Typo in the plugin name in the agent config stanza; plugin binary not present in plugin_dir; wrong `type` field (e.g. "driver" vs actual registered type); agent config copied from another host without installing the plugin.

Related errors


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