hashicorp/nomad · error
CSI.ControllerValidateVolume: %v
Error message
CSI.ControllerValidateVolume: %v
What it means
ControllerValidateVolume fails when req.ToCSIRequest() cannot convert the Nomad-side request into a CSI protocol request (validating required fields such as volume ID, plugin ID, capabilities). The error is prefixed with the method name and returned unwrapped (not retryable).
Source
Thrown at client/csi_endpoint.go:64
return errors.New("CSI.ControllerValidateVolume: VolumeID is required")
}
if req.PluginID == "" {
return errors.New("CSI.ControllerValidateVolume: PluginID is required")
}
plugin, err := c.findControllerPlugin(req.PluginID)
if err != nil {
// the server's view of the plugin health is stale, so let it know it
// should retry with another controller instance
return fmt.Errorf("CSI.ControllerValidateVolume: %w: %v",
nstructs.ErrCSIClientRPCRetryable, err)
}
defer plugin.Close()
csiReq, err := req.ToCSIRequest()
if err != nil {
return fmt.Errorf("CSI.ControllerValidateVolume: %v", err)
}
ctx, cancelFn := c.requestContext()
defer cancelFn()
// CSI ValidateVolumeCapabilities errors for timeout, codes.Unavailable and
// codes.ResourceExhausted are retried; all other errors are fatal.
err = plugin.ControllerValidateCapabilities(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.ControllerValidateVolume: %v", err)
}
return nil
}
// ControllerAttachVolume is used to attach a volume from a CSI Cluster toView on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect the underlying %v cause to find which required request field failed validation
- Fix the volume registration/job volume block so required fields (volume id, plugin id, capabilities) are populated
- Re-submit the volume registration or CSI RPC with a well-formed request
- Check server/client Nomad versions for skew causing struct incompatibility
Example fix
// before
req := &structs.ClientCSIControllerValidateVolumeRequest{PluginID: "aws-efs"} // VolumeID empty
// after
req := &structs.ClientCSIControllerValidateVolumeRequest{PluginID: "aws-efs", VolumeID: volID, VolumeContext: ctx, Caps: caps} Defensive patterns
Strategy: validation
Validate before calling
func validateControllerValidateReq(req *structs.ClientCSIControllerValidateVolumeRequest) error {
if req.PluginID == "" { return errors.New("PluginID required") }
if req.VolumeID == "" { return errors.New("VolumeID required") }
if len(req.Caps) == 0 { return errors.New("capabilities required") }
return nil
} Try / catch
if err := validateControllerValidateReq(req); err != nil {
// fix request fields before the RPC; this error is fatal, not retryable
return fmt.Errorf("invalid request: %w", err)
} Prevention
- Validate volume registrations with `nomad volume inspect` before validating capabilities
- Keep server and client Nomad versions in lockstep
- Populate Caps and VolumeContext from the volume registration, not ad-hoc
- Test CSI RPC payloads in CI with representative volume specs
When it happens
Trigger: Calling ControllerValidateVolume with a request struct missing required fields, so ToCSIRequest returns a validation error before any gRPC call to the plugin.
Common situations: A volume registration with malformed/empty capability or volume fields; a server bug after a structs schema change (version skew between server and client); hand-crafted RPCs in tests or custom tooling.
Related errors
- CSI.ControllerAttachVolume: %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/68bacdb85402bfb0.
Report an issue: GitHub.