{"record":{"id":"179b7b93ad9339da","repo":"hashicorp/nomad","slug":"no-such-volume-q","errorCode":null,"errorMessage":"no such volume %q","messagePattern":"no such volume %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/csi_endpoint.go","lineNumber":1623,"sourceCode":"\tif err != nil {\n\t\treturn err\n\t}\n\n\tmethod := \"ClientCSI.ControllerCreateSnapshot\"\n\tvar mErr multierror.Error\n\tfor _, snap := range args.Snapshots {\n\t\tif snap == nil {\n\t\t\t// we intentionally don't multierror here because we're in a weird state\n\t\t\treturn fmt.Errorf(\"snapshot cannot be nil\")\n\t\t}\n\n\t\tvol, err := state.CSIVolumeByID(nil, args.RequestNamespace(), snap.SourceVolumeID)\n\t\tif err != nil {\n\t\t\tmultierror.Append(&mErr, fmt.Errorf(\"error querying volume %q: %v\", snap.SourceVolumeID, err))\n\t\t\tcontinue\n\t\t}\n\t\tif vol == nil {\n\t\t\tmultierror.Append(&mErr, fmt.Errorf(\"no such volume %q\", snap.SourceVolumeID))\n\t\t\tcontinue\n\t\t}\n\n\t\tpluginID := snap.PluginID\n\t\tif pluginID == \"\" {\n\t\t\tpluginID = vol.PluginID\n\t\t}\n\n\t\tplugin, err := state.CSIPluginByID(nil, pluginID)\n\t\tif err != nil {\n\t\t\tmultierror.Append(&mErr,\n\t\t\t\tfmt.Errorf(\"error querying plugin %q: %v\", pluginID, err))\n\t\t\tcontinue\n\t\t}\n\t\tif plugin == nil {\n\t\t\tmultierror.Append(&mErr, fmt.Errorf(\"no such plugin %q\", pluginID))\n\t\t\tcontinue\n\t\t}","sourceCodeStart":1605,"sourceCodeEnd":1641,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/csi_endpoint.go#L1605-L1641","documentation":"CreateSnapshot appends 'no such volume %q' to the multierror when CSIVolumeByID succeeds but returns a nil volume, meaning the SourceVolumeID given in the snapshot request does not exist in Nomad's state store in the requested namespace. Each offending snapshot is skipped (continue) while remaining snapshots in the batch are still processed.","triggerScenarios":"Calling CreateSnapshot with a Snapshots entry whose SourceVolumeID is not a volume registered in Nomad: a typo'd volume ID, the volume was deregistered/deleted, or the volume exists in a different namespace than args.RequestNamespace() resolves to.","commonSituations":"Snapshot automation referencing a volume name instead of the full volume ID; volumes deleted after their job stopped; cross-namespace snapshots where the caller's token/namespace resolves differently than where the volume lives; stale config after a Nomad cluster state reset.","solutions":["List existing volumes (`nomad volume status` or GET /v1/volumes) and correct SourceVolumeID to an existing volume in the target namespace","Check the namespace: the volume may exist but in another namespace — either move the snapshot request to that namespace or grant cross-namespace access","Re-create/register the missing volume (nomad volume create / re-run the volume registration job) if it was deleted","Inspect the returned multierror to see which specific SourceVolumeIDs failed and fix each"],"exampleFix":"// before\n{\"Snapshots\":[{\"SourceVolumeID\":\"db-data\",\"PluginID\":\"ebs\"}]}\n// after: use the registered volume ID in the correct namespace\n{\"Snapshots\":[{\"SourceVolumeID\":\"db-data[0]\",\"PluginID\":\"ebs\"}]} // ID from `nomad volume status`","handlingStrategy":"validation","validationCode":"vols, _, err := client.Volumes().List(ctx, namespace, nil)\nif err != nil { return err }\nknown := map[string]bool{}\nfor _, v := range vols { known[v.ID] = true }\nfor _, s := range req.Snapshots {\n    if !known[s.SourceVolumeID] { return fmt.Errorf(\"volume %q not in namespace %q\", s.SourceVolumeID, namespace) }\n}","typeGuard":"func volumeExists(id string, vols []*api.VolumeListStub) bool {\n    for _, v := range vols { if v.ID == id { return true } }\n    return false\n}","tryCatchPattern":"if err := createSnapshot(req); err != nil {\n    if me, ok := err.(*multierror.Error); ok {\n        for _, e := range me.Errors {\n            if strings.Contains(e.Error(), \"no such volume\") {\n                // drop that snapshot entry from req and retry the remainder\n            }\n        }\n    }\n}","preventionTips":["Reference volumes by their registered ID from `nomad volume status`, not job-local names","Include the correct namespace in snapshot requests and ensure the token can read it","Reconcile snapshot configs against the live volume list periodically to catch deleted volumes"],"tags":["nomad","csi","snapshot","volume-not-found"],"backgroundTag":"volume-not-found","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}