hashicorp/nomad · error

must specify plugin type to dispense

Error message

must specify plugin type to dispense

What it means

DispensePlugin looks up a registered dispenser function by plugin type. An empty type cannot match any registered dispenser, so the registry immediately returns this developer-aid error before any lookup.

Source

Thrown at client/dynamicplugins/registry.go:374

		if delay < maxDelay {
			delay += delay
		}
		if delay > maxDelay {
			delay = maxDelay
		}
		timer.Reset(time.Duration(delay) * time.Millisecond)
	}
}

func (d *dynamicRegistry) DispensePlugin(ptype string, name string) (any, 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 nil, errors.New("must specify plugin type to dispense")
	}
	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 nil, errors.New("must specify plugin name to dispense")
	}

	dispenseFunc, ok := d.dispensers[ptype]
	if !ok {
		// This error shouldn't make it to a production cluster and is to aid
		// developers during the development of new plugin types.
		return nil, fmt.Errorf("no plugin dispenser found for type: %s", ptype)
	}

	// 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 {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Pass the correct plugin type constant (e.g. dynamicplugins.PluginTypeCSIDriver or PluginTypeCSINode)
  2. Validate ptype is non-empty before dispensing
  3. Check the upstream struct/request field that supplies the type and fix why it is empty

Example fix

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

Strategy: validation

Validate before calling

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

Type guard

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

Try / catch

plugin, err := registry.DispensePlugin(ptype, name)
if err != nil {
    if strings.Contains(err.Error(), "must specify plugin type") {
        return fmt.Errorf("dispense failed: unknown/empty plugin type %q: %w", ptype, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Registry.DispensePlugin(ptype, name) with ptype == "", e.g. a volume/driver manager that obtains the plugin type from a request field that is empty.

Common situations: CSI volume mount/unmount workflows where the driver's plugin type was not resolved, or code passing an empty string after a failed type inference.

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