hashicorp/nomad · error

ExternalVolumeID is required

Error message

ExternalVolumeID is required

What it means

NodeExpandVolumeRequest.Validate in plugins/csi/plugin.go:1057 requires ExternalVolumeID, the plugin-side identifier of the volume being expanded. Nomad joins all validation failures with errors.Join; this one fires when the ID field is the empty string. Without it the CSI plugin cannot identify which volume to resize.

Source

Thrown at plugins/csi/plugin.go:1057

	}
	return &csipbv1.CapacityRange{
		RequiredBytes: c.RequiredBytes,
		LimitBytes:    c.LimitBytes,
	}
}

type NodeExpandVolumeRequest struct {
	ExternalVolumeID string
	CapacityRange    *CapacityRange
	Capability       *VolumeCapability
	TargetPath       string
	StagingPath      string
}

func (r *NodeExpandVolumeRequest) Validate() error {
	var err error
	if r.ExternalVolumeID == "" {
		err = errors.Join(err, errors.New("ExternalVolumeID is required"))
	}
	if r.TargetPath == "" {
		err = errors.Join(err, errors.New("TargetPath is required"))
	}
	if e := r.CapacityRange.Validate(); e != nil {
		err = errors.Join(err, e)
	}
	return err
}

func (r *NodeExpandVolumeRequest) ToCSIRepresentation() *csipbv1.NodeExpandVolumeRequest {
	if r == nil {
		return nil
	}
	return &csipbv1.NodeExpandVolumeRequest{
		VolumeId:          r.ExternalVolumeID,
		VolumePath:        r.TargetPath,
		StagingTargetPath: r.StagingPath,

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Provide the external volume ID (the ID the storage provider returned at ControllerCreateVolume) in the request
  2. Resolve the Nomad volume to its external ID first (nomad volume status / CSI API) and pass that value
  3. Guard the calling code: reject empty volume IDs before invoking node expand

Example fix

// before
req := &csi.NodeExpandVolumeRequest{CapacityRange: cr}
// after
req := &csi.NodeExpandVolumeRequest{
    ExternalVolumeID: vol remoteID,
    TargetPath:       target,
    CapacityRange:    cr,
}
Defensive patterns

Strategy: validation

Validate before calling

if req.ExternalVolumeID == "" { return errors.New("ExternalVolumeID is required") }

Type guard

func expandable(req *csi.NodeExpandVolumeRequest) bool { return req.ExternalVolumeID != "" && req.TargetPath != "" }

Prevention

When it happens

Trigger: Calling node volume-expand against a CSI plugin with an empty ExternalNodeID/volume ID; constructing NodeExpandVolumeRequest in plugin tooling/tests without setting ExternalVolumeID; a lookup that failed to resolve the Nomad volume ID to the provider's external ID before this call.

Common situations: Scripts calling the Nomad agent CSI API with a missing volume ID parameter; custom CSI client code building the request struct directly; volume deregistered/resolved ID empty at expand time.

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/377ceff7dd5f4dc0. Report an issue: GitHub.