{"record":{"id":"35e70ea267eead07","repo":"hashicorp/nomad","slug":"no-plugin-dispenser-found-for-type-s","errorCode":null,"errorMessage":"no plugin dispenser found for type: %s","messagePattern":"no plugin dispenser found for type: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/dynamicplugins/registry.go","lineNumber":386,"sourceCode":"\td.pluginsLock.Lock()\n\tdefer d.pluginsLock.Unlock()\n\n\tif ptype == \"\" {\n\t\t// This error shouldn't make it to a production cluster and is to aid\n\t\t// developers during the development of new plugin types.\n\t\treturn nil, errors.New(\"must specify plugin type to dispense\")\n\t}\n\tif name == \"\" {\n\t\t// This error shouldn't make it to a production cluster and is to aid\n\t\t// developers during the development of new plugin types.\n\t\treturn nil, errors.New(\"must specify plugin name to dispense\")\n\t}\n\n\tdispenseFunc, ok := d.dispensers[ptype]\n\tif !ok {\n\t\t// This error shouldn't make it to a production cluster and is to aid\n\t\t// developers during the development of new plugin types.\n\t\treturn nil, fmt.Errorf(\"no plugin dispenser found for type: %s\", ptype)\n\t}\n\n\t// After initially loading the dispenser (to avoid masking missing setup in\n\t// client/client.go), we then check to see if we have any stub dispensers for\n\t// this plugin type. If we do, then replace the dispenser fn with the stub.\n\tif d.stubDispensers != nil {\n\t\tif stub, ok := d.stubDispensers[ptype]; ok {\n\t\t\tdispenseFunc = stub\n\t\t}\n\t}\n\n\tpmap, ok := d.plugins[ptype]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"no plugins registered for type: %s\", ptype)\n\t}\n\n\tinfo, ok := pmap[name]\n\tif !ok || info.Front() == nil {","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/dynamicplugins/registry.go#L368-L404","documentation":"DispensePlugin in the Nomad dynamic plugin registry looks up a dispenser function for the requested plugin type in d.dispensers. This error means no dispenser was registered for that plugin type. The source comment notes it is a developer aid that \"shouldn't make it to a production cluster\": dispensers are wired up in client/client.go at startup, so its presence usually indicates missing setup for a new plugin type or a code path running before/without that setup.","triggerScenarios":"Calling registry.DispensePlugin(ptype, name) with a ptype for which no dispenser was registered via RegisterDispenser; typically a new/custom plugin type whose dispenser wiring was not added in the client setup, or a misspelled plugin type string.","commonSituations":"Developing a new Nomad dynamic plugin type and forgetting to register its dispenser; typos in plugin type constants passed to task runners or CSI/DSL code paths; running a plugin consumer against a client build that lacks the dispenser registration.","solutions":["Verify the plugin type string matches an existing registered type (e.g. docker, csi) - check for typos or wrong constants.","Ensure RegisterDispenser(ptype, fn) is called for the type before DispensePlugin (usually in client/client.go setup for built-in types).","If adding a new plugin type, add both the dispenser registration and plugin-dispenser map entry in the client setup.","Check that the registry object being used is the fully-initialized client registry, not a fresh dynamicRegistry created in tests or a stub."],"exampleFix":"// before\nclient, _ := client.NewClient(cfg)\np, err := client.GetDynamicPluginsRegistry().DispensePlugin(\"myplugin\", \"name\")\n// after (register the dispenser first, e.g. in client setup)\nregistry.RegisterDispenser(\"myplugin\", func(info *dynamicplugins.PluginInfo) (interface{}, error) { return newMyPlugin(info), nil })\np, err := registry.DispensePlugin(\"myplugin\", \"name\")","handlingStrategy":"validation","validationCode":"// check the dispenser exists before dispensing\nif !registry.KnownPluginTypes()[ptype] { // or maintain your own allowlist of registered types\n    return fmt.Errorf(\"plugin type %q has no dispenser registered on this client\", ptype)\n}","typeGuard":null,"tryCatchPattern":"p, err := registry.DispensePlugin(ptype, name)\nif err != nil {\n    if strings.Contains(err.Error(), \"no plugin dispenser found\") {\n        // dev-time wiring bug: fail fast with context\n        return fmt.Errorf(\"dispenser for %q not wired up (register it in client setup): %w\", ptype, err)\n    }\n    return err\n}","preventionTips":["Keep plugin type strings in named constants shared between registration and dispensing code.","Register every new plugin type's dispenser in client setup as part of the same PR that introduces the type.","Add a unit test that DispensePlugin succeeds for every known plugin type."],"tags":["plugin-registry","nomad","go","runtime-lookup"],"backgroundTag":"plugin-dispenser-not-registered","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"}