hashicorp/nomad · error

must specify plugin name to dispense

Error message

must specify plugin name to dispense

What it means

Developer-aid guard in dynamicRegistry.DispensePlugin: the plugin name argument is empty. Per the surrounding code this should not reach production clusters; it exists to catch mistakes while developing new plugin types.

Source

Thrown at client/dynamicplugins/registry.go:379

			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 {
		if stub, ok := d.stubDispensers[ptype]; ok {
			dispenseFunc = stub
		}
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Pass the plugin name exactly as registered via RegisterPlugin
  2. Validate the name before dispensing
  3. Verify the volume/task request carries the expected plugin name (e.g. volume.PluginID)

Example fix

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

Strategy: validation

Validate before calling

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

Prevention

When it happens

Trigger: Calling Registry.DispensePlugin(ptype, "") with an empty plugin name, commonly when the CSI controller/node code passes a plugin name resolved from a volume request that is empty.

Common situations: Volume operations where the required plugin name was never populated on the volume or client request, or after renaming a plugin while old state still references it.

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