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
- Ensure ClientCSINodeID is set — it comes from the node's CSI node registration; re-run node fingerprint/CSI node registration
- Verify the volume registration has complete VolumeContext and volume ID
- Upgrade/align server and client Nomad versions if the server is sending incomplete requests
- 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
- Ensure `csi_node` fingerprint ran on the node so ClientCSINodeID exists
- Re-run node registration if the node was re-fingerprinted
- Keep server/client Nomad versions aligned
- Validate volume registration fields with `nomad volume inspect` before publish
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
- CSI.ControllerValidateVolume: %v
- missing secret ID
- CSI.ControllerValidateVolume: VolumeID is required
- CSI.ControllerValidateVolume: PluginID is required
- CSI.ControllerAttachVolume: VolumeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/6aecfbb6c7f71418.
Report an issue: GitHub.