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

  1. Check for double or out-of-order Register/Deregister calls for the plugin; ensure registration happens before deregistration.
  2. Restart the nomad client so the registry is rebuilt and plugin re-registers.
  3. Inspect nomad client logs for the plugin lifecycle events to identify the ordering bug; report/fix the registration handler if reproducible.
  4. 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

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


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