hashicorp/nomad · error
missing volumeID
Error message
missing volumeID
What it means
NodeUnstageVolume in the Nomad CSI client wrapper returns this sentinel error before ever issuing a gRPC call when the volumeID argument is an empty string. The source comments that these errors 'should not be returned during production use but exist as aids during Nomad development' — they guard against the Nomad CSI plugin's own internal caller passing empty identifiers to the underlying CSI NodeUnstageVolume RPC. It is a fail-fast developer aid, not a remote failure.
Source
Thrown at plugins/csi/client.go:831
case codes.FailedPrecondition:
err = fmt.Errorf("volume %q does not have MULTI_NODE volume capability: %v",
req.ExternalID, err)
case codes.Internal:
err = fmt.Errorf("node plugin returned an internal error, check the plugin allocation logs for more information: %v", err)
}
}
return err
}
func (c *client) NodeUnstageVolume(ctx context.Context, volumeID string, stagingTargetPath string, opts ...grpc.CallOption) error {
if err := c.ensureConnected(ctx); err != nil {
return err
}
// These errors should not be returned during production use but exist as aids
// during Nomad development
if volumeID == "" {
return fmt.Errorf("missing volumeID")
}
if stagingTargetPath == "" {
return fmt.Errorf("missing stagingTargetPath")
}
req := &csipbv1.NodeUnstageVolumeRequest{
VolumeId: volumeID,
StagingTargetPath: stagingTargetPath,
}
// NodeUnstageVolume's response contains no extra data. If err == nil, we were
// successful.
_, err := c.nodeClient.NodeUnstageVolume(ctx, req, opts...)
if err != nil {
code := status.Code(err)
switch code {
case codes.NotFound:
err = fmt.Errorf("%w: volume %q could not be found: %v",View on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the volume record (csivolumes) has a valid ExternalID before calling NodeUnstageVolume
- Log and inspect the caller's volume state; the empty ID usually indicates an upstream Nomad bug, not user misconfiguration
- Check the Nomad version for known bugs in volume claim untracking and upgrade
- Skip/report the call: an empty volumeID means there is nothing to unstage, so no cleanup is lost
Example fix
// before
csi.Client.NodeUnstageVolume(ctx, vol.ID, stagingPath)
// after
if vol.ID == "" {
logger.Warn("skipping unstage: volume ID already empty")
return nil
}
csi.Client.NodeUnstageVolume(ctx, vol.ID, stagingPath) Defensive patterns
Strategy: validation
Validate before calling
if volumeID == "" {
return fmt.Errorf("cannot unstage: volumeID is empty; check the volume claim record")
}
// proceed to client.NodeUnstageVolume(ctx, volumeID, stagingTargetPath) Type guard
func hasVolumeID(id string) bool { return strings.TrimSpace(id) != "" } Try / catch
err := client.NodeUnstageVolume(ctx, volumeID, stagingPath)
if err != nil && strings.Contains(err.Error(), "missing volumeID") {
// developer-aid error: log volume state and skip; nothing to unstage
logger.Warn("unstage skipped: empty volumeID", "claim", claim)
return nil
}
return err Prevention
- Never call NodeUnstageVolume without a non-empty ExternalID from the volume claim record
- Validate volume state after agent restore/checkpoint before cleanup hooks run
- Write tests covering unstage with partially populated claim structs
When it happens
Trigger: Calling client.NodeUnstageVolume(ctx, "", stagingTargetPath) with an empty volumeID, typically from a task-runner hook or volume unmounting path where the CSI volume's ExternalID was never populated or was lost during a restore/checkpoint.
Common situations: Nomad development/testing of new volume integration code; volumes whose registration records were corrupted or partially restored after agent restart; custom tooling invoking the CSI client directly with unverified volume state.
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
- missing stagingTargetPath
- %w: volume %q could not be found: %v
- validation error: %v
- volume row conversion error
- structs.ErrUnknownAllocationPrefix
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/c4a6827b05206475.
Report an issue: GitHub.