hashicorp/nomad · error

must specify plugin name to deregister

Error message

must specify plugin name to deregister

What it means

DeregisterPlugin needs the plugin name to find the specific registration within the type's plugin map. An empty name makes the deregistration ambiguous, so it is rejected with this developer-aid error.

Source

Thrown at client/dynamicplugins/registry.go:252

		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 {
		// plugin already deregistered, don't send events or try re-deleting.
		return nil
	}

	var info *PluginInfo

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Pass the plugin name that was used at RegisterPlugin time
  2. Validate the name is non-empty at the call site
  3. Verify the deregistering handler reads the name from the correct field of the request/struct

Example fix

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

Strategy: validation

Validate before calling

if name == "" {
    return fmt.Errorf("deregister: plugin name 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 name") {
        return fmt.Errorf("cannot deregister %s plugin: name missing: %w", ptype, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Registry.DeregisterPlugin(ptype, "", allocID) with an empty name, e.g. when a CSI node plugin's deregistration handler passes an empty plugin name from a request or stale state.

Common situations: Alloc/deregistration event handlers building the name from a field that is unset, or cleanup code after an upgrade where the plugin name field changed.

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/b41f07d218f33fef. Report an issue: GitHub.