{"record":{"id":"377ceff7dd5f4dc0","repo":"hashicorp/nomad","slug":"externalvolumeid-is-required","errorCode":null,"errorMessage":"ExternalVolumeID is required","messagePattern":"ExternalVolumeID is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/csi/plugin.go","lineNumber":1057,"sourceCode":"\t}\n\treturn &csipbv1.CapacityRange{\n\t\tRequiredBytes: c.RequiredBytes,\n\t\tLimitBytes:    c.LimitBytes,\n\t}\n}\n\ntype NodeExpandVolumeRequest struct {\n\tExternalVolumeID string\n\tCapacityRange    *CapacityRange\n\tCapability       *VolumeCapability\n\tTargetPath       string\n\tStagingPath      string\n}\n\nfunc (r *NodeExpandVolumeRequest) Validate() error {\n\tvar err error\n\tif r.ExternalVolumeID == \"\" {\n\t\terr = errors.Join(err, errors.New(\"ExternalVolumeID is required\"))\n\t}\n\tif r.TargetPath == \"\" {\n\t\terr = errors.Join(err, errors.New(\"TargetPath is required\"))\n\t}\n\tif e := r.CapacityRange.Validate(); e != nil {\n\t\terr = errors.Join(err, e)\n\t}\n\treturn err\n}\n\nfunc (r *NodeExpandVolumeRequest) ToCSIRepresentation() *csipbv1.NodeExpandVolumeRequest {\n\tif r == nil {\n\t\treturn nil\n\t}\n\treturn &csipbv1.NodeExpandVolumeRequest{\n\t\tVolumeId:          r.ExternalVolumeID,\n\t\tVolumePath:        r.TargetPath,\n\t\tStagingTargetPath: r.StagingPath,","sourceCodeStart":1039,"sourceCodeEnd":1075,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/plugins/csi/plugin.go#L1039-L1075","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Provide the external volume ID (the ID the storage provider returned at ControllerCreateVolume) in the request","Resolve the Nomad volume to its external ID first (nomad volume status / CSI API) and pass that value","Guard the calling code: reject empty volume IDs before invoking node expand"],"exampleFix":"// before\nreq := &csi.NodeExpandVolumeRequest{CapacityRange: cr}\n// after\nreq := &csi.NodeExpandVolumeRequest{\n    ExternalVolumeID: vol remoteID,\n    TargetPath:       target,\n    CapacityRange:    cr,\n}","handlingStrategy":"validation","validationCode":"if req.ExternalVolumeID == \"\" { return errors.New(\"ExternalVolumeID is required\") }","typeGuard":"func expandable(req *csi.NodeExpandVolumeRequest) bool { return req.ExternalVolumeID != \"\" && req.TargetPath != \"\" }","tryCatchPattern":null,"preventionTips":["Resolve the provider's external volume ID before expanding","Fail fast on empty IDs in client code","Ensure volume exists/published before expand"],"tags":["csi","validation","volume-expand"],"backgroundTag":"missing-required-argument","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"}