{"record":{"id":"ac186c98f01953f9","repo":"hashicorp/nomad","slug":"plugin-does-not-support-listing-snapshots","errorCode":null,"errorMessage":"plugin does not support listing snapshots","messagePattern":"plugin does not support listing snapshots","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/csi_endpoint.go","lineNumber":1788,"sourceCode":"\t// NOTE: this is the plugin's namespace, not the volume(s) because they\n\t// might not even be registered\n\tif !allowVolume(aclObj, args.RequestNamespace()) {\n\t\treturn structs.ErrPermissionDenied\n\t}\n\tsnap, err := v.srv.fsm.State().Snapshot()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tplugin, err := snap.CSIPluginByID(nil, args.PluginID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif plugin == nil {\n\t\treturn fmt.Errorf(\"no such plugin\")\n\t}\n\tif !plugin.HasControllerCapability(structs.CSIControllerSupportsListSnapshots) {\n\t\treturn fmt.Errorf(\"plugin does not support listing snapshots\")\n\t}\n\n\tmethod := \"ClientCSI.ControllerListSnapshots\"\n\tcReq := &cstructs.ClientCSIControllerListSnapshotsRequest{\n\t\tMaxEntries:    args.PerPage,\n\t\tStartingToken: args.NextToken,\n\t\tSecrets:       args.Secrets,\n\t}\n\tcReq.PluginID = plugin.ID\n\tcResp := &cstructs.ClientCSIControllerListSnapshotsResponse{}\n\n\terr = v.srv.RPC(method, cReq, cResp)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif args.PerPage > 0 && args.PerPage < int32(len(cResp.Entries)) {\n\t\t// this should be done in the plugin already, but enforce it\n\t\treply.Snapshots = cResp.Entries[:args.PerPage]","sourceCodeStart":1770,"sourceCodeEnd":1806,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/csi_endpoint.go#L1770-L1806","documentation":"Nomad's CSI ListSnapshots RPC forwards a ControllerListSnapshots request to a CSI plugin's controller. This error is thrown when the target CSI plugin exists but its controller capabilities do not advertise CSI ControllerService Capability LIST_SNAPSHOTS, so Nomad refuses to send a call the plugin cannot answer.","triggerScenarios":"Calling GET /v1/plugins/snapshots (or ClientCSI ControllerListSnapshots via nomad csi snapshot list) against a plugin that was registered without CSIControllerSupportsListSnapshots in its controller capability set — typically a plugin whose controller only supports create/delete/attach, or a controller-only plugin built from an older CSI spec.","commonSituations":"Using a storage vendor's driver version that predates snapshot listing support; a plugin registered as controller-capable for other operations but without LIST_SNAPSHOTS; misconfigured plugin csi_spec_version; attempting snapshot listing on drivers that only implement node-level snapshots.","solutions":["Verify the plugin's controller capabilities: nomad plugin status <plugin-id> and check it advertises list-snapshots support","Upgrade the CSI plugin/driver to a version that implements ControllerListSnapshots (CSI spec >= 1.2 with LIST_SNAPSHOTS controller capability)","List snapshots directly from the storage backend or via the driver's own tooling instead of through Nomad","If using an external snapshotter, ensure the snapshot controller sidecar is deployed alongside the driver"],"exampleFix":"// before: querying snapshots against a plugin without the capability\nnomad plugin status aws-ebs-csi-driver   # no list-snapshots cap\nnomad csi snapshot list\n// Error: plugin does not support listing snapshots\n\n// after: upgrade the driver or check capability first\ncapabilities=$(curl -s --unix-socket /run/csi/socket http://localhost/... )\n# deploy a driver build that declares LIST_SNAPSHOTS controller capability, then:\nnomad csi snapshot list","handlingStrategy":"validation","validationCode":"p, err := client.CSIPlugins().Get(pluginID)\nif err != nil { return err }\nif !hasCap(p.ControllerCapabilities, \"LIST_SNAPSHOTS\") {\n    return fmt.Errorf(\"plugin %s cannot list snapshots\", pluginID)\n}","typeGuard":"func supportsListSnapshots(caps []string) bool {\n    for _, c := range caps {\n        if c == \"LIST_SNAPSHOTS\" { return true }\n    }\n    return false\n}","tryCatchPattern":"snaps, err := client.CSISnapshots().List(opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"does not support listing snapshots\") {\n        return nil, fmt.Errorf(\"driver %s lacks snapshot support; use backend tooling\", driver)\n    }\n    return nil, err\n}","preventionTips":["Check nomad plugin status for controller capabilities before using snapshot APIs","Pin CSI driver versions that declare LIST_SNAPSHOTS controller capability","Feature-detect at deploy time rather than at first snapshot-list call","Document per-driver snapshot support in your platform docs"],"tags":["csi","storage","snapshots","nomad","capability-check"],"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"}