hashicorp/nomad · error
CSI.ControllerDetachVolume: VolumeID is required
Error message
CSI.ControllerDetachVolume: VolumeID is required
What it means
ControllerDetachVolume validates the detach request before forwarding it to the CSI controller plugin. An empty VolumeID returns this error. Like the attach checks, it is a defensive development aid and should not occur on a properly functioning cluster.
Source
Thrown at client/csi_endpoint.go:155
// the storage node provided in the request.
func (c *CSI) ControllerDetachVolume(req *structs.ClientCSIControllerDetachVolumeRequest, resp *structs.ClientCSIControllerDetachVolumeResponse) error {
defer metrics.MeasureSince([]string{"client", "csi_controller", "unpublish_volume"}, time.Now())
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.ControllerDetachVolume: %w: %v",
nstructs.ErrCSIClientRPCRetryable, err)
}
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.ControllerDetachVolume: VolumeID is required")
}
if req.ClientCSINodeID == "" {
return errors.New("CSI.ControllerDetachVolume: ClientCSINodeID is required")
}
csiReq := req.ToCSIRequest()
// Submit the request for a volume to the CSI Plugin.
ctx, cancelFn := c.requestContext()
defer cancelFn()
// CSI ControllerUnpublishVolume errors for timeout, codes.Unavailable and
// codes.ResourceExhausted are retried; all other errors are fatal.
_, err = plugin.ControllerUnpublishVolume(ctx, csiReq,
grpc_retry.WithPerRetryTimeout(CSIPluginRequestTimeout),
grpc_retry.WithMax(3),
grpc_retry.WithBackoff(grpc_retry.BackoffExponential(100*time.Millisecond)))
if errors.Is(err, nstructs.ErrCSIClientRPCIgnorable) {View on GitHub (pinned to 482b49bf1a)
Solutions
- Set req.VolumeID to the CSI volume ID before calling
- Skip the controller detach if the volume ID is unknown (nothing to detach) and clean up local state instead
- Trace why the volume record disappeared — check for races between GC and detach
Example fix
// before
req := &structs.ControllerDetachVolumeRequest{ClientCSINodeID: nodeID, ExternalID: extID}
// after
if volID == "" { return nil // already unregistered, skip controller detach }
req := &structs.ControllerDetachVolumeRequest{VolumeID: volID, ClientCSINodeID: nodeID, ExternalID: extID} Defensive patterns
Strategy: validation
Validate before calling
if req == nil || req.VolumeID == "" {
return errors.New("ControllerDetachVolume requires a non-empty VolumeID")
} Type guard
func detachable(req *structs.ControllerDetachVolumeRequest) bool {
return req != nil && req.VolumeID != ""
} Try / catch
if err := client.ControllerDetachVolume(req, &resp); err != nil {
if strings.Contains(err.Error(), "VolumeID is required") {
return nil // nothing to detach; volume already gone
}
return err
} Prevention
- Resolve the volume record before detach and skip if absent
- Order GC after controller detach completes
- Log-and-skip instead of failing the unclaim loop when the ID is missing
When it happens
Trigger: Calling the client's ControllerDetachVolume RPC with req.VolumeID == "" — e.g. detaching from a claim whose volume record is missing, or constructing the request manually.
Common situations: Volume already purged from state store while detach is still scheduled; unmount/node-unclaim flows that never resolved the volume ID; test harness code.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- CSI.ControllerAttachVolume: VolumeID is required
- CSI.ControllerAttachVolume: ClientCSINodeID is required
- CSI.ControllerDetachVolume: ClientCSINodeID is required
- CSI.NodeDetachVolume: PluginID is required
- CSI.NodeDetachVolume: VolumeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/9314c7bfed0673ff.
Report an issue: GitHub.