{"record":{"id":"91ab1c2ab3268346","repo":"hashicorp/nomad","slug":"plugin-does-not-support-snapshot","errorCode":null,"errorMessage":"plugin does not support snapshot","messagePattern":"plugin does not support snapshot","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/csi_endpoint.go","lineNumber":1727,"sourceCode":"\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\tplugin, err := stateSnap.CSIPluginByID(nil, snap.PluginID)\n\t\tif err != nil {\n\t\t\tmultierror.Append(&mErr,\n\t\t\t\tfmt.Errorf(\"could not query plugin %q: %v\", snap.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\"))\n\t\t\tcontinue\n\t\t}\n\t\tif !plugin.HasControllerCapability(structs.CSIControllerSupportsCreateDeleteSnapshot) {\n\t\t\tmultierror.Append(&mErr, fmt.Errorf(\"plugin does not support snapshot\"))\n\t\t\tcontinue\n\t\t}\n\n\t\tmethod := \"ClientCSI.ControllerDeleteSnapshot\"\n\n\t\tcReq := &cstructs.ClientCSIControllerDeleteSnapshotRequest{\n\t\t\tID:      snap.ID,\n\t\t\tSecrets: snap.Secrets,\n\t\t}\n\t\tcReq.PluginID = plugin.ID\n\t\tcResp := &cstructs.ClientCSIControllerDeleteSnapshotResponse{}\n\t\terr = v.serializedControllerRPC(plugin.ID, func() error {\n\t\t\treturn v.srv.RPC(method, cReq, cResp)\n\t\t})\n\t\tif err != nil {\n\t\t\tmultierror.Append(&mErr, fmt.Errorf(\"could not delete %q: %v\", snap.ID, err))\n\t\t}\n\t}","sourceCodeStart":1709,"sourceCodeEnd":1745,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/csi_endpoint.go#L1709-L1745","documentation":"Raised in CSIVolume.DeleteSnapshot when the plugin exists but lacks the CSI controller capability CSIControllerSupportsCreateDeleteSnapshot. Snapshot creation/deletion is a controller-level operation; a plugin registered as node-only (or whose controller does not advertise snapshot support) cannot delete snapshots, so a per-snapshot error is appended and the snapshot is skipped.","triggerScenarios":"Calling DeleteSnapshot against a plugin whose ControllerRequired/Capabilities do not include CSIControllerSupportsCreateDeleteSnapshot — e.g. a node-only plugin, or a controller whose CSI driver does not implement CREATE_DELETE_SNAPSHOT.","commonSituations":"Deploying a plugin job without controller capability (ControllerRequired missing/false); using a storage driver whose controller does not support snapshots; Nomad plugin registration differing from what the CSI driver actually supports.","solutions":["Update the plugin job so the controller capability is enabled (ControllerRequired = true) and re-register the plugin.","Verify the storage driver actually implements the CSI snapshot controller capability; if not, manage snapshots at the storage provider directly.","Check `nomad plugin status <id>` for the plugin's controller capabilities before attempting snapshot operations.","Use a plugin/driver version that supports snapshots if the current one does not."],"exampleFix":"// before — plugin job without controller capability\ntype = \"csi-plugin\"\n# controller block missing\n// after\nplugin {\n  type = \"csi-plugin\"\n  controller_required = true\n  csi_plugin {\n    id = \"aws-ebs\"\n  }\n}","handlingStrategy":"validation","validationCode":"plug, _, _ := client.CSI().GetPlugin(pluginID, nil)\nif plug == nil { return errors.New(\"plugin not registered\") }\nfor _, c := range plug.Controllers {\n    for _, cap := range c.Capabilities {\n        if cap.Type == api.CSIControllerSupportsCreateDeleteSnapshot { return nil }\n    }\n}\nreturn fmt.Errorf(\"plugin %s does not support snapshot delete\", pluginID)","typeGuard":"func supportsSnapshotDelete(p *api.CSIPlugin) bool {\n    if p == nil { return false }\n    for _, c := range p.Controllers {\n        for _, cap := range c.Capabilities {\n            if cap.Type == api.CSIControllerSupportsCreateDeleteSnapshot { return true }\n        }\n    }\n    return false\n}","tryCatchPattern":"if strings.Contains(err.Error(), \"plugin does not support snapshot\") {\n    log.Printf(\"snapshot %s must be managed at the storage provider directly\", snapID)\n    return nil\n}","preventionTips":["Deploy plugin jobs with controller_required = true and snapshot controller capabilities for snapshot workflows.","Check plugin controller capabilities in `nomad plugin status` before snapshot operations.","Verify the storage driver supports CSI snapshot controller capabilities (not all do).","Keep driver versions current — older drivers may lack snapshot support."],"tags":["csi","plugin-capability","snapshot","controller"],"backgroundTag":"csi-capability-unsupported","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"}