hashicorp/nomad · error
CSI.ControllerValidateVolume: VolumeID is required
Error message
CSI.ControllerValidateVolume: VolumeID is required
What it means
ControllerValidateVolume performs request validation before contacting the CSI plugin and rejects requests with an empty VolumeID. The VolumeID identifies which volume to validate against the plugin; without it the request is malformed. The error is returned directly to the caller of CSI.ControllerValidateVolume.
Source
Thrown at client/csi_endpoint.go:46
const (
// CSIPluginRequestTimeout is the timeout that should be used when making reqs
// against CSI Plugins. It is copied from Kubernetes as an initial seed value.
// https://github.com/kubernetes/kubernetes/blob/e680ad7156f263a6d8129cc0117fda58602e50ad/pkg/volume/csi/csi_plugin.go#L52
CSIPluginRequestTimeout = 2 * time.Minute
)
var (
ErrPluginTypeError = errors.New("CSI Plugin loaded incorrectly")
)
// ControllerValidateVolume is used during volume registration to validate
// that a volume exists and that the capabilities it was registered with are
// supported by the CSI Plugin and external volume configuration.
func (c *CSI) ControllerValidateVolume(req *structs.ClientCSIControllerValidateVolumeRequest, resp *structs.ClientCSIControllerValidateVolumeResponse) error {
defer metrics.MeasureSince([]string{"client", "csi_controller", "validate_volume"}, time.Now())
if req.VolumeID == "" {
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)View on GitHub (pinned to 482b49bf1a)
Solutions
- Set req.VolumeID to the volume's UUID before issuing the validate-volume request
- Ensure the upstream volume lookup succeeded and its ID was propagated into the request
- Validate client-side before the RPC: fail fast if the resolved volume ID is empty
Example fix
// before
req := &structs.ClientCSIControllerValidateVolumeRequest{PluginID: pluginID, VolumeContext: ctx}
c.CSI.ControllerValidateVolume(req, resp) // VolumeID is required
// after
req := &structs.ClientCSIControllerValidateVolumeRequest{VolumeID: volumeID, PluginID: pluginID, VolumeContext: ctx}
if volumeID == "" { return fmt.Errorf("volume not found: cannot validate empty VolumeID") } Defensive patterns
Strategy: validation
Validate before calling
if req.VolumeID == "" {
return fmt.Errorf("cannot validate volume: VolumeID is empty; ensure the volume lookup succeeded")
} Type guard
func validValidateVolumeRequest(req *structs.ClientCSIControllerValidateVolumeRequest) bool {
return req != nil && req.VolumeID != "" && req.PluginID != ""
} Try / catch
if err := c.CSI.ControllerValidateVolume(req, resp); err != nil {
if strings.Contains(err.Error(), "VolumeID is required") {
return fmt.Errorf("volume ID unresolved before validation: %w", err)
}
return err
} Prevention
- Resolve the volume UUID via the volume API before issuing validate requests
- Propagate VolumeID through job/volume specs so it isn't dropped in serialization
- Fail fast on empty lookup results instead of passing empty strings downstream
- Add unit tests covering the empty-VolumeID request path
When it happens
Trigger: Calling ControllerValidateVolume (or issuing a ClientCSIControllerValidateVolumeRequest via RPC) with req.VolumeID == "".
Common situations: Caller resolved the volume by a name/ID lookup that failed and silently passed an empty string; serialized job/volume spec missing the volume ID field; API client bug constructing the request struct without setting VolumeID.
Related errors
- CSI.ControllerValidateVolume: PluginID is required
- volume clone ID cannot be updated
- volume requested capabilities update was not compatible with
- missing volume claim
- unknown volume attachment mode: %s
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/7bf593479ee40e8c.
Report an issue: GitHub.