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
- Pass the correct plugin type constant (e.g. dynamicplugins.PluginTypeCSIDriver or PluginTypeCSINode)
- Validate ptype is non-empty before dispensing
- 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
- Pass dynamicplugins.PluginType* constants, never user-supplied raw strings
- Resolve plugin type from the registered plugin info, not from optional request fields
- Add assertions that dispenser lookup inputs are non-empty
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
- Plugin.Name must not be empty
- must specify plugin type to deregister
- must specify plugin name to deregister
- must specify plugin allocation ID to deregister
- must specify plugin name to dispense
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5f43e2925e52804b.
Report an issue: GitHub.