{"record":{"id":"e6068f1d5dc4b175","repo":"hashicorp/nomad","slug":"controller-validate-volume-v","errorCode":null,"errorMessage":"controller validate volume: %v","messagePattern":"controller validate volume: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/client_csi_endpoint.go","lineNumber":56,"sourceCode":"\t\t\"ClientCSI.ControllerAttachVolume\",\n\t\tstructs.RateMetricWrite,\n\t\targs, reply)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"controller attach volume: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc (a *ClientCSI) ControllerValidateVolume(args *cstructs.ClientCSIControllerValidateVolumeRequest, reply *cstructs.ClientCSIControllerValidateVolumeResponse) error {\n\tdefer metrics.MeasureSince([]string{\"nomad\", \"client_csi_controller\", \"validate_volume\"}, time.Now())\n\n\terr := a.sendCSIControllerRPC(args.PluginID,\n\t\t\"CSI.ControllerValidateVolume\",\n\t\t\"ClientCSI.ControllerValidateVolume\",\n\t\tstructs.RateMetricWrite,\n\t\targs, reply)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"controller validate volume: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc (a *ClientCSI) ControllerDetachVolume(args *cstructs.ClientCSIControllerDetachVolumeRequest, reply *cstructs.ClientCSIControllerDetachVolumeResponse) error {\n\tdefer metrics.MeasureSince([]string{\"nomad\", \"client_csi_controller\", \"detach_volume\"}, time.Now())\n\n\terr := a.sendCSIControllerRPC(args.PluginID,\n\t\t\"CSI.ControllerDetachVolume\",\n\t\t\"ClientCSI.ControllerDetachVolume\",\n\t\tstructs.RateMetricWrite,\n\t\targs, reply)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"controller detach volume: %v\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/client_csi_endpoint.go#L38-L74","documentation":"ClientCSI.ControllerValidateVolume forwards a CSI ControllerValidateVolume RPC to the CSI controller plugin via sendCSIControllerRPC, and wraps any forwarding failure as \"controller validate volume: <err>\". Validation is invoked before volume claims are created, so this error surfaces during volume registration or job placement when the controller cannot validate the volume.","triggerScenarios":"`nomad volume register`/volume claim path when the controller plugin is unavailable, the plugin returns an error from ControllerValidateVolumeCapabilities, or the RPC to the plugin fails.","commonSituations":"Volume spec's requested capabilities don't match what the plugin advertises and the plugin returns an error; controller plugin down; plugin_id mismatch in the volume spec; CSI plugin implements validation incorrectly.","solutions":["Run `nomad volume status <vol-id>` and compare the volume's requested capabilities with the plugin's advertised ones.","Confirm the controller plugin is running/healthy (`nomad plugin status`) and re-register the volume after fixing plugin_id.","Inspect plugin alloc logs for the plugin-side validation error and adjust the volume spec capabilities."],"exampleFix":"// before\ncapability { access_mode = \"multi-node-multi-writer\"\n  attachment_mode = \"file-system\" }\n// after\n# match modes the controller plugin actually supports\ncapability { access_mode = \"single-node-writer\"\n  attachment_mode = \"file-system\" }","handlingStrategy":"try-catch","validationCode":"const plugin = await nomad.plugin(pluginID)\nif (!plugin.controllers?.some(c => c.healthy)) {\n  throw new Error(`controller ${pluginID} down; volume validation would fail`)\n}\n// also compare requested capabilities against advertised ones\nconst advertised = new Set(plugin.capabilities ?? [])\nfor (const cap of volume.requestedCapabilities) {\n  if (!advertised.has(cap)) throw new Error(`capability ${cap} not supported by plugin`)\n}","typeGuard":null,"tryCatchPattern":"try { await validateVolume(spec) }\ncatch (e) {\n  if (String(e).startsWith('controller validate volume')) {\n    log.warn('CSI validation failed:', e); return { valid: false, reason: e }\n  }\n  throw e\n}","preventionTips":["Match volume capability blocks exactly to what the plugin advertises.","Re-register volumes after any plugin_id change.","Test volume registration in a staging cluster after CSI plugin upgrades.","Keep controller and node plugins of the same provider at compatible versions."],"tags":["nomad","csi","storage","validation","plugin"],"backgroundTag":"csi-controller-rpc-failed","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"}