hashicorp/nomad · warning
no plugins registered for type: %s
Error message
no plugins registered for type: %s
What it means
DeregisterPlugin in the dynamic plugin registry looks up the plugin-type map (d.plugins[ptype]) before removing a named plugin. If no map exists for that plugin type, the code comments that this indicates a bug in the registration handler and returns this error. It means deregistration was attempted for a plugin type that was never registered.
Source
Thrown at client/dynamicplugins/registry.go:261
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 errors.New("must specify plugin type to deregister")
}
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 errors.New("must specify plugin name to deregister")
}
if allocID == "" {
return errors.New("must specify plugin allocation ID to deregister")
}
pmap, ok := d.plugins[ptype]
if !ok {
// If this occurs there's a bug in the registration handler.
return fmt.Errorf("no plugins registered for type: %s", ptype)
}
infos, ok := pmap[name]
if !ok {
// plugin already deregistered, don't send events or try re-deleting.
return nil
}
var info *PluginInfo
for e := infos.Front(); e != nil; e = e.Next() {
info = e.Value.(*PluginInfo)
if info.AllocID == allocID {
infos.Remove(e)
break
}
}
if info != nil {View on GitHub (pinned to 482b49bf1a)
Solutions
- Check for double or out-of-order Register/Deregister calls for the plugin; ensure registration happens before deregistration.
- Restart the nomad client so the registry is rebuilt and plugin re-registers.
- Inspect nomad client logs for the plugin lifecycle events to identify the ordering bug; report/fix the registration handler if reproducible.
- Verify the CSI plugin task is healthy and re-emits its registration on client start.
Example fix
// before: deregistering a type that was never registered registry.DeregisterPlugin(dynamic.PluginTypeCSINode, allocID, name) // after: register first, then deregister registry.RegisterPlugin(info) // during plugin startup // ...later... registry.DeregisterPlugin(dynamic.PluginTypeCSINode, allocID, name)
Defensive patterns
Strategy: try-catch
Validate before calling
// only deregister plugin types that were registered
if _, err := registry.Get(ptype, name); err != nil { /* not registered: skip deregister */ } Try / catch
if err := registry.DeregisterPlugin(ptype, allocID, name); err != nil && strings.Contains(err.Error(), "no plugins registered for type") {
// registration never happened or registry restarted; treat as idempotent no-op or re-register
log.Warnf("deregister for unregistered plugin type %s: %v", ptype, err)
} Prevention
- Always call RegisterPlugin before any possible DeregisterPlugin
- Re-register plugins on client restart so registry state is rebuilt
- Watch for out-of-order plugin lifecycle events after server reconnects
When it happens
Trigger: A CSI plugin deregistration event is delivered for a ptype (e.g. 'csi-node'/'csi-controller') for which the registry has no map — normally only after an inconsistent registration/deregistration sequence, since the normal path returns nil when a plugin is simply already deregistered.
Common situations: Server reconnect replays deregistration events out of order; a bug in the CSI plugin registration handler; registry restarted losing its maps while events still arrive; plugin task events racing client restarts.
Related errors
- Plugin.Type must not be empty
- Plugin.ConnectionInfo must not be nil
- error parsing: root should be an object
- missing policy name
- cannot specify Accessor ID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/face4a1c2984894e.
Report an issue: GitHub.