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
- Confirm the exact plugin name used at RegisterPlugin time (check the plugin's job/alloc and the client registry logs).
- Check the plugin allocation is running; if it stopped, restart it so the plugin re-registers.
- Correct the name in the caller's config (task/volume/CSI config) to match the registered plugin ID.
- 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
- Source plugin names from the same config/job values used to register them - avoid hand-typed duplicates.
- Watch PluginsUpdatedCh for deregistration events and invalidate cached references.
- Log the list of registered plugin names on startup to make name mismatches obvious.
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
- no plugin dispenser found for type: %s
- no plugin for that allocation
- must pass non-nil job
- job is missing ID
- ErrLockConflict
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/a4651d7dadbfb4a6.
Report an issue: GitHub.