{"record":{"id":"7bf593479ee40e8c","repo":"hashicorp/nomad","slug":"csi-controllervalidatevolume-volumeid-is-required","errorCode":null,"errorMessage":"CSI.ControllerValidateVolume: VolumeID is required","messagePattern":"CSI\\.ControllerValidateVolume: VolumeID is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/csi_endpoint.go","lineNumber":46,"sourceCode":"const (\n\t// CSIPluginRequestTimeout is the timeout that should be used when making reqs\n\t// against CSI Plugins. It is copied from Kubernetes as an initial seed value.\n\t// https://github.com/kubernetes/kubernetes/blob/e680ad7156f263a6d8129cc0117fda58602e50ad/pkg/volume/csi/csi_plugin.go#L52\n\tCSIPluginRequestTimeout = 2 * time.Minute\n)\n\nvar (\n\tErrPluginTypeError = errors.New(\"CSI Plugin loaded incorrectly\")\n)\n\n// ControllerValidateVolume is used during volume registration to validate\n// that a volume exists and that the capabilities it was registered with are\n// supported by the CSI Plugin and external volume configuration.\nfunc (c *CSI) ControllerValidateVolume(req *structs.ClientCSIControllerValidateVolumeRequest, resp *structs.ClientCSIControllerValidateVolumeResponse) error {\n\tdefer metrics.MeasureSince([]string{\"client\", \"csi_controller\", \"validate_volume\"}, time.Now())\n\n\tif req.VolumeID == \"\" {\n\t\treturn errors.New(\"CSI.ControllerValidateVolume: VolumeID is required\")\n\t}\n\n\tif req.PluginID == \"\" {\n\t\treturn errors.New(\"CSI.ControllerValidateVolume: PluginID is required\")\n\t}\n\n\tplugin, err := c.findControllerPlugin(req.PluginID)\n\tif err != nil {\n\t\t// the server's view of the plugin health is stale, so let it know it\n\t\t// should retry with another controller instance\n\t\treturn fmt.Errorf(\"CSI.ControllerValidateVolume: %w: %v\",\n\t\t\tnstructs.ErrCSIClientRPCRetryable, err)\n\t}\n\tdefer plugin.Close()\n\n\tcsiReq, err := req.ToCSIRequest()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"CSI.ControllerValidateVolume: %v\", err)","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/csi_endpoint.go#L28-L64","documentation":"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.","triggerScenarios":"Calling ControllerValidateVolume (or issuing a ClientCSIControllerValidateVolumeRequest via RPC) with req.VolumeID == \"\".","commonSituations":"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.","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"],"exampleFix":"// before\nreq := &structs.ClientCSIControllerValidateVolumeRequest{PluginID: pluginID, VolumeContext: ctx}\nc.CSI.ControllerValidateVolume(req, resp) // VolumeID is required\n// after\nreq := &structs.ClientCSIControllerValidateVolumeRequest{VolumeID: volumeID, PluginID: pluginID, VolumeContext: ctx}\nif volumeID == \"\" { return fmt.Errorf(\"volume not found: cannot validate empty VolumeID\") }","handlingStrategy":"validation","validationCode":"if req.VolumeID == \"\" {\n    return fmt.Errorf(\"cannot validate volume: VolumeID is empty; ensure the volume lookup succeeded\")\n}","typeGuard":"func validValidateVolumeRequest(req *structs.ClientCSIControllerValidateVolumeRequest) bool {\n    return req != nil && req.VolumeID != \"\" && req.PluginID != \"\"\n}","tryCatchPattern":"if err := c.CSI.ControllerValidateVolume(req, resp); err != nil {\n    if strings.Contains(err.Error(), \"VolumeID is required\") {\n        return fmt.Errorf(\"volume ID unresolved before validation: %w\", err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["csi","validation","volume","request"],"backgroundTag":"missing-required-request-field","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}