hashicorp/nomad · error

CSI.ControllerAttachVolume: %v

Error message

CSI.ControllerAttachVolume: %v

What it means

ControllerAttachVolume returns this when req.ToCSIRequest() cannot build a valid CSI ControllerPublishVolume request, or (per the source block) when required fields like VolumeID or ClientCSINodeID are empty — these should have been validated server-side before reaching the client.

Source

Thrown at client/csi_endpoint.go:116

	}
	defer plugin.Close()

	// The following block of validation checks should not be reached on a
	// real Nomad cluster as all of this data should be validated when registering
	// volumes with the cluster. They serve as a defensive check before forwarding
	// requests to plugins, and to aid with development.

	if req.VolumeID == "" {
		return errors.New("CSI.ControllerAttachVolume: VolumeID is required")
	}

	if req.ClientCSINodeID == "" {
		return errors.New("CSI.ControllerAttachVolume: ClientCSINodeID is required")
	}

	csiReq, err := req.ToCSIRequest()
	if err != nil {
		return fmt.Errorf("CSI.ControllerAttachVolume: %v", err)
	}

	// Submit the request for a volume to the CSI Plugin.
	ctx, cancelFn := c.requestContext()
	defer cancelFn()
	// CSI ControllerPublishVolume errors for timeout, codes.Unavailable and
	// codes.ResourceExhausted are retried; all other errors are fatal.
	cresp, err := plugin.ControllerPublishVolume(ctx, csiReq,
		grpc_retry.WithPerRetryTimeout(CSIPluginRequestTimeout),
		grpc_retry.WithMax(3),
		grpc_retry.WithBackoff(grpc_retry.BackoffExponential(100*time.Millisecond)))
	if err != nil {
		return fmt.Errorf("CSI.ControllerAttachVolume: %v", err)
	}

	resp.PublishContext = cresp.PublishContext
	return nil
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure ClientCSINodeID is set — it comes from the node's CSI node registration; re-run node fingerprint/CSI node registration
  2. Verify the volume registration has complete VolumeContext and volume ID
  3. Upgrade/align server and client Nomad versions if the server is sending incomplete requests
  4. Re-issue the volume publish workflow after correcting the request

Example fix

// before
req := &structs.ClientCSIControllerAttachVolumeRequest{PluginID: p, VolumeID: v} // ClientCSINodeID missing
// after
req := &structs.ClientCSIControllerAttachVolumeRequest{PluginID: p, VolumeID: v, ClientCSINodeID: nodeID}
Defensive patterns

Strategy: validation

Validate before calling

func validateAttachReq(req *structs.ClientCSIControllerAttachVolumeRequest) error {
    if req.VolumeID == "" { return errors.New("VolumeID is required") }
    if req.ClientCSINodeID == "" { return errors.New("ClientCSINodeID is required") }
    if req.PluginID == "" { return errors.New("PluginID is required") }
    return nil
}

Try / catch

if err := validateAttachReq(req); err != nil {
    // correct node CSI registration / volume registration before retrying
    return fmt.Errorf("skip attach, invalid request: %w", err)
}

Prevention

When it happens

Trigger: Calling ControllerAttachVolume with a request missing VolumeID, ControllerName/PluginID, or ClientCSINodeID (the ClientCSINodeID=="" check returns the plain errors.New variant), or ToCSIRequest failing on malformed fields.

Common situations: A Nomad server bug or version skew emitting an under-populated controller attach request; custom automation invoking the client RPC directly with partial data; volume registration missing fields normally filled by the server.

Related errors


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