hashicorp/nomad · error

no plugin dispenser found for type: %s

Error message

no plugin dispenser found for type: %s

What it means

DispensePlugin in the Nomad dynamic plugin registry looks up a dispenser function for the requested plugin type in d.dispensers. This error means no dispenser was registered for that plugin type. The source comment notes it is a developer aid that "shouldn't make it to a production cluster": dispensers are wired up in client/client.go at startup, so its presence usually indicates missing setup for a new plugin type or a code path running before/without that setup.

Source

Thrown at client/dynamicplugins/registry.go:386

	d.pluginsLock.Lock()
	defer d.pluginsLock.Unlock()

	if ptype == "" {
		// This error shouldn't make it to a production cluster and is to aid
		// developers during the development of new plugin types.
		return nil, errors.New("must specify plugin type to dispense")
	}
	if name == "" {
		// This error shouldn't make it to a production cluster and is to aid
		// developers during the development of new plugin types.
		return nil, errors.New("must specify plugin name to dispense")
	}

	dispenseFunc, ok := d.dispensers[ptype]
	if !ok {
		// This error shouldn't make it to a production cluster and is to aid
		// developers during the development of new plugin types.
		return nil, fmt.Errorf("no plugin dispenser found for type: %s", ptype)
	}

	// After initially loading the dispenser (to avoid masking missing setup in
	// client/client.go), we then check to see if we have any stub dispensers for
	// this plugin type. If we do, then replace the dispenser fn with the stub.
	if d.stubDispensers != nil {
		if stub, ok := d.stubDispensers[ptype]; ok {
			dispenseFunc = stub
		}
	}

	pmap, ok := d.plugins[ptype]
	if !ok {
		return nil, fmt.Errorf("no plugins registered for type: %s", ptype)
	}

	info, ok := pmap[name]
	if !ok || info.Front() == nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the plugin type string matches an existing registered type (e.g. docker, csi) - check for typos or wrong constants.
  2. Ensure RegisterDispenser(ptype, fn) is called for the type before DispensePlugin (usually in client/client.go setup for built-in types).
  3. If adding a new plugin type, add both the dispenser registration and plugin-dispenser map entry in the client setup.
  4. Check that the registry object being used is the fully-initialized client registry, not a fresh dynamicRegistry created in tests or a stub.

Example fix

// before
client, _ := client.NewClient(cfg)
p, err := client.GetDynamicPluginsRegistry().DispensePlugin("myplugin", "name")
// after (register the dispenser first, e.g. in client setup)
registry.RegisterDispenser("myplugin", func(info *dynamicplugins.PluginInfo) (interface{}, error) { return newMyPlugin(info), nil })
p, err := registry.DispensePlugin("myplugin", "name")
Defensive patterns

Strategy: validation

Validate before calling

// check the dispenser exists before dispensing
if !registry.KnownPluginTypes()[ptype] { // or maintain your own allowlist of registered types
    return fmt.Errorf("plugin type %q has no dispenser registered on this client", ptype)
}

Try / catch

p, err := registry.DispensePlugin(ptype, name)
if err != nil {
    if strings.Contains(err.Error(), "no plugin dispenser found") {
        // dev-time wiring bug: fail fast with context
        return fmt.Errorf("dispenser for %q not wired up (register it in client setup): %w", ptype, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling registry.DispensePlugin(ptype, name) with a ptype for which no dispenser was registered via RegisterDispenser; typically a new/custom plugin type whose dispenser wiring was not added in the client setup, or a misspelled plugin type string.

Common situations: Developing a new Nomad dynamic plugin type and forgetting to register its dispenser; typos in plugin type constants passed to task runners or CSI/DSL code paths; running a plugin consumer against a client build that lacks the dispenser registration.

Related errors


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