hashicorp/nomad · error
CSI.NodeDetachVolume: VolumeID is required
Error message
CSI.NodeDetachVolume: VolumeID is required
What it means
NodeDetachVolume requires the VolumeID so the plugin manager can find the volume usage / detach the right volume on the node. An empty VolumeID returns this defensive error before contacting the plugin.
Source
Thrown at client/csi_endpoint.go:510
}
}
return nil
}
// NodeDetachVolume is used to detach a volume from a CSI Cluster from
// the storage node provided in the request.
func (c *CSI) NodeDetachVolume(req *structs.ClientCSINodeDetachVolumeRequest, resp *structs.ClientCSINodeDetachVolumeResponse) error {
defer metrics.MeasureSince([]string{"client", "csi_node", "detach_volume"}, time.Now())
// The following block of validation checks should not be reached on a
// real Nomad cluster. They serve as a defensive check before forwarding
// requests to plugins, and to aid with development.
if req.PluginID == "" {
return errors.New("CSI.NodeDetachVolume: PluginID is required")
}
if req.VolumeID == "" {
return errors.New("CSI.NodeDetachVolume: VolumeID is required")
}
if req.AllocID == "" {
return errors.New("CSI.NodeDetachVolume: AllocID is required")
}
ctx, cancelFn := c.requestContext()
defer cancelFn()
manager, err := c.c.csimanager.ManagerForPlugin(ctx, req.PluginID)
if err != nil {
return fmt.Errorf("CSI.NodeDetachVolume: %v", err)
}
usageOpts := &csimanager.UsageOptions{
ReadOnly: req.ReadOnly,
AttachmentMode: req.AttachmentMode,
AccessMode: req.AccessMode,
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Set req.VolumeID from the allocation's volume claim (alloc.AllocatedResources.VolumeClaims[].VolumeID)
- Skip the detach when no claim exists (nothing was mounted)
- Check for races between claim GC and detach
Example fix
// before
req := &structs.NodeDetachVolumeRequest{PluginID: pluginID, AllocID: allocID}
// after
if claim.VolumeID == "" { return nil }
req := &structs.NodeDetachVolumeRequest{PluginID: pluginID, VolumeID: claim.VolumeID, AllocID: allocID} Defensive patterns
Strategy: validation
Validate before calling
if req == nil || req.VolumeID == "" {
return errors.New("NodeDetachVolume requires a non-empty VolumeID")
} Type guard
func detachNodeReady(req *structs.NodeDetachVolumeRequest) bool {
return req != nil && req.PluginID != "" && req.VolumeID != "" && req.AllocID != ""
} Try / catch
if err := client.NodeDetachVolume(req, &resp); err != nil {
if strings.Contains(err.Error(), "VolumeID is required") {
return nil // no claim to detach
}
return err
} Prevention
- Derive VolumeID from the alloc's volume claims before unmount
- Skip detaches for allocations with no volume claims
- Test GC/unmount ordering to avoid lost volume IDs
When it happens
Trigger: Calling NodeDetachVolume with req.VolumeID == "" — e.g. when the claim's volume ID was lost or the caller only had the allocation and forgot to resolve the volume.
Common situations: Unmount paths iterating allocations without carrying the volume ID; volume deregistered concurrently; manual test RPCs.
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: VolumeID is required
- CSI.ControllerDetachVolume: ClientCSINodeID is required
- CSI.NodeDetachVolume: PluginID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5282b838aba89601.
Report an issue: GitHub.