{"record":{"id":"8a4cfee8738440a1","repo":"hashicorp/nomad","slug":"missing-volumeid","errorCode":null,"errorMessage":"missing VolumeID","messagePattern":"missing VolumeID","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/csi/plugin.go","lineNumber":774,"sourceCode":"type ControllerCreateSnapshotRequest struct {\n\tVolumeID   string\n\tName       string\n\tSecrets    structs.CSISecrets\n\tParameters map[string]string\n}\n\nfunc (r *ControllerCreateSnapshotRequest) ToCSIRepresentation() *csipbv1.CreateSnapshotRequest {\n\treturn &csipbv1.CreateSnapshotRequest{\n\t\tSourceVolumeId: r.VolumeID,\n\t\tName:           r.Name,\n\t\tSecrets:        r.Secrets,\n\t\tParameters:     r.Parameters,\n\t}\n}\n\nfunc (r *ControllerCreateSnapshotRequest) Validate() error {\n\tif r.VolumeID == \"\" {\n\t\treturn errors.New(\"missing VolumeID\")\n\t}\n\tif r.Name == \"\" {\n\t\treturn errors.New(\"missing Name\")\n\t}\n\treturn nil\n}\n\ntype ControllerCreateSnapshotResponse struct {\n\tSnapshot *Snapshot\n}\n\ntype Snapshot struct {\n\tID             string\n\tSourceVolumeID string\n\tSizeBytes      int64\n\tCreateTime     int64\n\tIsReady        bool\n}","sourceCodeStart":756,"sourceCodeEnd":792,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/plugins/csi/plugin.go#L756-L792","documentation":"This error is returned by ControllerCreateSnapshotRequest.Validate when VolumeID is empty. Creating a snapshot requires identifying the source volume by its provider-assigned ID; without it the snapshot has no target, so the request is rejected locally before the ControllerCreateSnapshot gRPC call.","triggerScenarios":"Calling the create-snapshot path with ControllerCreateSnapshotRequest{VolumeID: \"\", Name: \"snap1\"} — e.g. the volume ID variable was empty because the volume was never created/published, or the request struct was built without setting VolumeID.","commonSituations":"Snapshot automation running before volume registration completed; a lookup of the volume by name returning an empty ID that was passed through unvalidated; templating an ID from an unset Nomad variable.","solutions":["Populate VolumeID with the provider-assigned external volume ID before snapshotting.","Verify the source volume exists via nomad volume status and copy its external ID.","Guard the snapshot job to wait until the volume is fully registered/published.","Validate VolumeID non-empty at the automation layer with a clearer message."],"exampleFix":"// before\nsnap := &ControllerCreateSnapshotRequest{Name: \"nightly\"}\n// after\nsnap := &ControllerCreateSnapshotRequest{\n  VolumeID: vol.ExternalID,\n  Name:     \"nightly\",\n}","handlingStrategy":"validation","validationCode":"if req.VolumeID == \"\" {\n\treturn fmt.Errorf(\"cannot snapshot: source volume ID is required\")\n}","typeGuard":"func snapshotTargetSet(r *ControllerCreateSnapshotRequest) bool {\n\treturn r != nil && r.VolumeID != \"\" && r.Name != \"\"\n}","tryCatchPattern":null,"preventionTips":["Gate snapshot jobs on volume registration completing successfully.","Never pass through an empty ID from a failed volume lookup.","Resolve volume names to external IDs via nomad volume status before snapshotting."],"tags":["csi","validation","missing-field","snapshot","storage"],"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"}