hashicorp/nomad · error

plugin %s for type csi-node not found

Error message

plugin %s for type csi-node not found

What it means

ManagerForPlugin found registered csi-node plugins on this client but none matches the requested pluginID. This is an ID mismatch between the volume's plugin_id and the CSI plugins actually initialized in the manager's instances map.

Source

Thrown at client/pluginmanager/csimanager/manager.go:106

		return fmt.Errorf("%s plugin '%s' did not become ready: %w", pType, pID, err)
	}
	c.instancesLock.Lock()
	defer c.instancesLock.Unlock()
	c.ensureInstance(p)
	return nil
}

func (c *csiManager) ManagerForPlugin(ctx context.Context, pluginID string) (VolumeManager, error) {
	c.instancesLock.RLock()
	defer c.instancesLock.RUnlock()
	nodePlugins, hasAnyNodePlugins := c.instances["csi-node"]
	if !hasAnyNodePlugins {
		return nil, fmt.Errorf("no storage node plugins found")
	}

	mgr, hasPlugin := nodePlugins[pluginID]
	if !hasPlugin {
		return nil, fmt.Errorf("plugin %s for type csi-node not found", pluginID)
	}

	return mgr.VolumeManager(ctx)
}

// Run starts a plugin manager and should return early
func (c *csiManager) Run() {
	go c.runLoop()
}

func (c *csiManager) runLoop() {
	timer := time.NewTimer(0) // ensure we sync immediately in first pass
	controllerUpdates := c.registry.PluginsUpdatedCh(c.shutdownCtx, "csi-controller")
	nodeUpdates := c.registry.PluginsUpdatedCh(c.shutdownCtx, "csi-node")
	for {
		select {
		case <-timer.C:
			c.resyncPluginsFromRegistry("csi-controller")

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify plugin_id in the volume specification exactly matches the CSI node plugin ID on the node (nomad node status -verbose)
  2. Correct the volume spec's plugin_id or rename the plugin job to match
  3. Add scheduling constraints so allocations using this volume land on nodes running the specified plugin
  4. Re-register the volume (nomad volume update/deregister+register) if the plugin ID changed

Example fix

// before: mismatched plugin id in volume spec
volume "data" {
  type = "csi"
  plugin_id = "aws-ebs-controller" // wrong
  ...
}

// after
type csiVolume struct {
  PluginID string `hcl:"plugin_id"`
}
func (v csiVolume) validate() error {
  if v.PluginID != "aws-ebs-node" {
    return fmt.Errorf("plugin_id must match the node plugin, got %q", v.PluginID)
  }
  return nil
}
Defensive patterns

Strategy: validation

Validate before calling

node, _, _ := client.Nodes().Info(nodeID, nil)
found := false
for _, p := range node.CSIControllerPlugins { if p.ID == pluginID { found = true } }
for _, p := range node.CSINodePlugins { if p.ID == pluginID { found = true } }
if !found {
	return fmt.Errorf("plugin_id %q not registered on node %s; fix volume spec or plugin placement", pluginID, nodeID)
}

Try / catch

mgr, err := manager.ManagerForPlugin(ctx, pluginID)
if err != nil {
	if strings.Contains(err.Error(), "for type csi-node not found") {
		return fmt.Errorf("plugin_id %q mismatch: check volume spec vs registered plugin IDs (nomad node status -verbose)", pluginID)
	}
	return err
}

Prevention

When it happens

Trigger: Mounting a CSI volume whose plugin_id does not match any node plugin registered on the client, e.g. typo in plugin_id in the volume spec, or volume created for a plugin deployed only on other nodes.

Common situations: Renaming a CSI plugin job without updating volume plugin_id; copy-pasting plugin_id from a controller plugin instead of the node plugin; multi-plugin clusters where the workload landed on a node running a different plugin.

Related errors


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