hashicorp/nomad · error

missing plugin ID

Error message

missing plugin ID

What it means

clientIDsForController requires a non-empty pluginID to look up the CSI plugin in state store; if the request's PluginID field is empty it returns 'missing plugin ID'. This guards against forwarding controller RPCs with no target plugin.

Source

Thrown at nomad/client_csi_endpoint.go:293

	// Make the RPC
	if err := NodeRpc(state.Session, method, args, reply); err != nil {
		return fmt.Errorf("%s error: %w", method, err)
	}
	return nil
}

// clientIDsForController returns a sorted list of client IDs where the
// controller plugin is expected to be running.
func (a *ClientCSI) clientIDsForController(pluginID string) ([]string, error) {

	snap, err := a.srv.State().Snapshot()
	if err != nil {
		return nil, err
	}

	if pluginID == "" {
		return nil, fmt.Errorf("missing plugin ID")
	}

	ws := memdb.NewWatchSet()

	// note: plugin IDs are not scoped to region but volumes are. so any Nomad
	// client we get for a controller is already in the same region for the
	// volume.
	plugin, err := snap.CSIPluginByID(ws, pluginID)
	if err != nil {
		return nil, fmt.Errorf("error getting plugin: %s, %v", pluginID, err)
	}
	if plugin == nil {
		return nil, fmt.Errorf("plugin missing: %s", pluginID)
	}

	clientIDs := []string{}

	if len(plugin.Controllers) == 0 {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set plugin_id in the request (e.g. pass -plugin to `nomad volume snapshots` or populate PluginID in the RPC args).
  2. Verify the volume spec declares plugin_id and re-register it.
  3. Upgrade the nomad CLI/tooling to a version that always sends PluginID.

Example fix

// before
req := &api.VolumeValidationRequest{} // PluginID empty
// after
req := &api.VolumeValidationRequest{PluginID: "aws-ebs-controller"}
Defensive patterns

Strategy: validation

Validate before calling

if req.PluginID == "" {
    return fmt.Errorf("PluginID is required for controller RPCs")
}
// proceed with the RPC

Type guard

func hasPluginID(args cstructs.CSIControllerRequest) bool {
    return args.GetPluginID() != ""
}

Try / catch

err := csi.ControllerListVolumes(args, reply)
if err != nil && strings.Contains(err.Error(), "missing plugin ID") {
    return fmt.Errorf("caller bug: PluginID not set: %w", err)
}

Prevention

When it happens

Trigger: A Controller* RPC (ListVolumes, Create/Delete/ListSnapshots, ControllerValidateCapacity, etc.) arrives with args.PluginID == "" — e.g. an API caller omitting plugin_id in the volume/endpoint request.

Common situations: Hand-built API requests or tooling that forgets the PluginID field; older clients or scripts written before plugin_id became a required field; copy-pasted request templates leaving the field blank.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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