{"record":{"id":"6c97766da65ebb43","repo":"hashicorp/nomad","slug":"missing-volume-id","errorCode":null,"errorMessage":"missing volume ID","messagePattern":"missing volume ID","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/csi/plugin.go","lineNumber":179,"sourceCode":"\tif r == nil {\n\t\treturn nil\n\t}\n\n\treturn &csipbv1.NodePublishVolumeRequest{\n\t\tVolumeId:          r.ExternalID,\n\t\tPublishContext:    r.PublishContext,\n\t\tStagingTargetPath: r.StagingTargetPath,\n\t\tTargetPath:        r.TargetPath,\n\t\tVolumeCapability:  r.VolumeCapability.ToCSIRepresentation(),\n\t\tReadonly:          r.Readonly,\n\t\tSecrets:           r.Secrets,\n\t\tVolumeContext:     r.VolumeContext,\n\t}\n}\n\nfunc (r *NodePublishVolumeRequest) Validate() error {\n\tif r.ExternalID == \"\" {\n\t\treturn errors.New(\"missing volume ID\")\n\t}\n\n\tif r.TargetPath == \"\" {\n\t\treturn errors.New(\"missing TargetPath\")\n\t}\n\n\tif r.VolumeCapability == nil {\n\t\treturn errors.New(\"missing VolumeCapabilities\")\n\t}\n\n\treturn nil\n}\n\ntype NodeStageVolumeRequest struct {\n\t// The external ID of the volume to stage.\n\tExternalID string\n\n\t// If the volume was attached via a call to `ControllerPublishVolume` then","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/plugins/csi/plugin.go#L161-L197","documentation":"NodePublishVolumeRequest.Validate in the CSI plugin layer requires the ExternalID field, which identifies the remote storage volume being mounted into a task. An empty ExternalID means Nomad's CSI client could not supply the provider's volume ID, so the request is rejected before being sent to the storage plugin. This guards against publishing a mount with no backing volume.","triggerScenarios":"A CSI NodePublishVolume RPC is issued with r.ExternalID == \"\" — typically when a volume claim resolved to a volume with no provider-assigned ExternalID, or code constructs the request manually without setting ExternalID.","commonSituations":"Malformed/empty CSI volume registration in the Nomad state store; a storage provider returning a volume without an ExternalID; hand-written Go code building a NodePublishVolumeRequest for tests or custom controllers omitting the field.","solutions":["Verify the volume was successfully created/registered with `nomad volume status <id>` and has a valid ExternalID","Re-register the volume (`nomad volume register`) with a correct CSI volume ID from the provider","Check that the CSI controller plugin CreateVolume returned a non-empty volume_id","If writing Go against the plugin API, set ExternalID before calling Validate"],"exampleFix":"// before\nreq := &csi.NodePublishVolumeRequest{TargetPath: \"/mnt/data\"}\n\n// after\nreq := &csi.NodePublishVolumeRequest{\n    ExternalID:  \"vol-0abc123\",\n    TargetPath:  \"/mnt/data\",\n}","handlingStrategy":"validation","validationCode":"if req.ExternalID == \"\" {\n    return fmt.Errorf(\"ExternalID is required\")\n}","typeGuard":null,"tryCatchPattern":"if err := req.Validate(); err != nil {\n    if strings.Contains(err.Error(), \"missing volume ID\") {\n        return fmt.Errorf(\"volume not registered with provider: %w\", err)\n    }\n    return err\n}","preventionTips":["Register volumes using the provider's real volume ID","Confirm ExternalID via `nomad volume status` before publishing","Run Validate on constructed requests in unit tests","Re-register volumes whose ExternalID is empty"],"tags":["csi","storage","validation","nomad"],"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"}