{"record":{"id":"63aebc80b1ccacee","repo":"hashicorp/nomad","slug":"no-such-plugin","errorCode":null,"errorMessage":"no such plugin","messagePattern":"no such plugin","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/csi_endpoint.go","lineNumber":1554,"sourceCode":"\t\treturn err\n\t}\n\n\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.CSIControllerSupportsListVolumes) {\n\t\treturn fmt.Errorf(\"unimplemented for this plugin\")\n\t}\n\n\tmethod := \"ClientCSI.ControllerListVolumes\"\n\tcReq := &cstructs.ClientCSIControllerListVolumesRequest{\n\t\tMaxEntries:    args.PerPage,\n\t\tStartingToken: args.NextToken,\n\t}\n\tcReq.PluginID = plugin.ID\n\tcResp := &cstructs.ClientCSIControllerListVolumesResponse{}\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)) {","sourceCodeStart":1536,"sourceCodeEnd":1572,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/csi_endpoint.go#L1536-L1572","documentation":"ListExternal in the Nomad server's CSI endpoint returns this when the state store query for the requested plugin ID succeeds but returns no plugin object. It means the CSIPluginID supplied in the ListExternal RPC does not correspond to any CSI plugin registered with Nomad's state store. The check is a deliberate explicit nil-guard after the store lookup rather than surfacing the store error.","triggerScenarios":"Calling nomad's ListExternal (CSI external volume listing) with args.PluginID that is not registered in Nomad: a typo'd plugin ID, a plugin whose controller plugin registration was garbage-collected/deregistered (node left, controller job stopped), or calling the CSI external list API before any controller plugin for that ID has registered with a Nomad client.","commonSituations":"Operators using `nomad volume snapshot list` / external volume listing against a plugin that was recently unregistered; plugin ID mismatch between ACL policies/scripts and the actual registered plugin name (e.g. 'aws-ebs' vs the controller job's registered ID); a Nomad client that hosted the controller left the cluster so the plugin was deregistered.","solutions":["List registered CSI plugins (`nomad plugin status` or the /v1/plugins API) and use the exact ID of an existing controller plugin in the ListExternal request","Re-register the missing plugin: run/redeploy the CSI controller job on a Nomad client so it registers with the expected ID","Fix the plugin ID in your tooling/config if it was typo'd or renamed","Check that the Nomad client running the controller plugin is up and connected (plugin deregistration follows node drain/failure)"],"exampleFix":"// before\nargs := &structs.CSIVolumeExternalListRequest{PluginID: \"aws-ebs\"}\n// after\nplugins, _, _ := client.Search(...). // or GET /v1/plugins?... \n// pick the actual registered ID, e.g. from `nomad plugin status`:\nargs := &structs.CSIVolumeExternalListRequest{PluginID: \"aws-ebs-controller\"}","handlingStrategy":"validation","validationCode":"plugin, _, err := client.Plugins().Get(ctx, pluginID, nil)\nif err != nil || plugin == nil {\n    return fmt.Errorf(\"plugin %q not registered with Nomad\", pluginID)\n}","typeGuard":"func pluginRegistered(p *api.CSIPlugin) bool { return p != nil && p.ID != \"\" }","tryCatchPattern":"if err := listExternal(pluginID); err != nil {\n    if strings.Contains(err.Error(), \"no such plugin\") {\n        // refresh plugin registry list and retry with a valid ID\n    } else { return err }\n}","preventionTips":["Resolve plugin IDs from `nomad plugin status` instead of hardcoding them","Watch for node drains/failures that deregister controller plugins and alert on plugin count changes","Re-run CSI controller jobs as part of cluster recovery so plugins re-register"],"tags":["nomad","csi","plugin-not-found","rpc"],"backgroundTag":"csi-plugin-not-found","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"}