hashicorp/nomad · error

plugin %s for type %s not found

Error message

plugin %s for type %s not found

What it means

DispensePlugin found the plugins map for the type but the specific named plugin is missing from it, or the list entry for that name is empty (info.Front() == nil). This means plugins of the type exist, but not the named instance requested. It is the name-scoped variant of the not-registered family.

Source

Thrown at client/dynamicplugins/registry.go:405

	}

	// 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 {
		return nil, fmt.Errorf("plugin %s for type %s not found", name, ptype)
	}

	return dispenseFunc(info.Front().Value.(*PluginInfo))
}

func (d *dynamicRegistry) PluginForAlloc(ptype, name, allocID string) (*PluginInfo, error) {
	d.pluginsLock.Lock()
	defer d.pluginsLock.Unlock()

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

	infos, ok := pmap[name]
	if ok {
		for e := infos.Front(); e != nil; e = e.Next() {
			plugin := e.Value.(*PluginInfo)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Confirm the exact plugin name used at RegisterPlugin time (check the plugin's job/alloc and the client registry logs).
  2. Check the plugin allocation is running; if it stopped, restart it so the plugin re-registers.
  3. Correct the name in the caller's config (task/volume/CSI config) to match the registered plugin ID.
  4. If a race with deregistration is possible, handle the error by waiting/retrying rather than failing the task hard.

Example fix

// before
_, err := registry.DispensePlugin("csi-controller", "ebs-prod") // wrong plugin ID
// after
_, err := registry.DispensePlugin("csi-controller", "aws-ebs") // matches RegisterPlugin name
Defensive patterns

Strategy: validation

Validate before calling

if name == "" {
    return fmt.Errorf("plugin name must be set before dispensing %s", ptype)
}
// optionally list registered names for the type and validate membership
for _, p := range registry.PluginsUpdatedCh(ptype) { /* use events to track known names */ }

Try / catch

p, err := registry.DispensePlugin(ptype, name)
if err != nil {
    var target *dynamicplugins.PluginInfo
    if strings.Contains(err.Error(), "not found") {
        return fmt.Errorf("plugin %q of type %q is not registered (check the plugin job is running and the name matches): %w", name, ptype, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling DispensePlugin(ptype, name) where ptype is registered but name is not present in pmap, or the entry's list is empty (plugin was deregistered, e.g. its allocation exited).

Common situations: Requesting a CSI controller/volume by a name that differs from the registered plugin name (case or suffix mismatch); the plugin allocation was rescheduled/stopped so its registration was removed; stale references in task config to an old plugin name.

Related errors


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