hashicorp/nomad · error

must specify plugin type to deregister

Error message

must specify plugin type to deregister

What it means

DeregisterPlugin requires both a plugin type and name to locate the registration to remove. The type parameter identifies which plugin map (e.g. csi-driver, csi-node) to search. An empty type means the lookup cannot proceed, so the registry returns this developer-aid error.

Source

Thrown at client/dynamicplugins/registry.go:247

	defer d.broadcastersLock.Unlock()

	broadcaster, ok := d.broadcasters[ptype]
	if !ok {
		broadcaster = newPluginEventBroadcaster()
		d.broadcasters[ptype] = broadcaster
	}

	return broadcaster
}

func (d *dynamicRegistry) DeregisterPlugin(ptype, name, allocID string) error {
	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 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 {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Pass the correct plugin type constant (e.g. dynamicplugins.PluginTypeCSIDriver) as the first argument
  2. Trace where ptype originates and validate it is non-empty before the call
  3. Log the caller arguments to identify which code path produces the empty type

Example fix

// before
err := registry.DeregisterPlugin("", pluginName, allocID)
// after
if ptype == "" {
    return fmt.Errorf("cannot deregister plugin %q: plugin type is empty", pluginName)
}
err := registry.DeregisterPlugin(ptype, pluginName, allocID)
Defensive patterns

Strategy: validation

Validate before calling

if ptype == "" {
    return fmt.Errorf("deregister: plugin type is required")
}
err := registry.DeregisterPlugin(ptype, name, allocID)

Type guard

func canDeregister(ptype, name, allocID string) bool {
    return ptype != "" && name != "" && allocID != ""
}

Try / catch

err := registry.DeregisterPlugin(ptype, name, allocID)
if err != nil {
    if strings.Contains(err.Error(), "must specify plugin type") {
        return fmt.Errorf("plugin type %q invalid: %w", ptype, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Registry.DeregisterPlugin(ptype, name, allocID) with ptype == "", usually when the caller's stored plugin type variable was never set or was lost during a type/attribute lookup.

Common situations: A plugin deregistration handler derives the type from a request field that is empty (e.g. job/ CSI plugin info missing), or refactored code passes the wrong variable position.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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