hashicorp/nomad · error
unable to dispense the executor plugin: %v
Error message
unable to dispense the executor plugin: %v
What it means
Returned when the go-plugin RPC connection succeeded but rpcClient.Dispense("executor") failed to produce the named plugin. go-plugin Dispense errors when the requested plugin name is not in the plugin set the client was configured with, meaning the PluginSet catalog in the ClientConfig does not contain an entry named "executor" (or the broker failed to dispense that plugin stub).
Source
Thrown at drivers/shared/executor/utils.go:111
if err != nil {
return nil, nil, err
}
if _, err := exec.Version(); err != nil {
return nil, nil, err
}
return exec, pluginClient, nil
}
func newExecutorClient(config *plugin.ClientConfig, logger hclog.Logger) (Executor, *plugin.Client, error) {
executorClient := plugin.NewClient(config)
rpcClient, err := executorClient.Client()
if err != nil {
return nil, nil, fmt.Errorf("error creating rpc client for executor plugin: %v", err)
}
raw, err := rpcClient.Dispense("executor")
if err != nil {
return nil, nil, fmt.Errorf("unable to dispense the executor plugin: %v", err)
}
executorPlugin, ok := raw.(Executor)
if !ok {
return nil, nil, fmt.Errorf("unexpected executor rpc type: %T", raw)
}
return executorPlugin, executorClient, nil
}
func processStateToProto(ps *ProcessState) (*proto.ProcessState, error) {
timestamp, err := ptypes.TimestampProto(ps.Time)
if err != nil {
return nil, err
}
pb := &proto.ProcessState{
Pid: int32(ps.Pid),
ExitCode: int32(ps.ExitCode),
Signal: int32(ps.Signal),
OomKilled: ps.OOMKilled,View on GitHub (pinned to 482b49bf1a)
Solutions
- Confirm the plugin.ClientConfig.Plugins map passed to newExecutorClient contains key "executor" mapped to the ExecutorPlugin implementation
- Ensure launcher and reattacher are the same Nomad version so the plugin set matches
- Rebuild/redeploy the client binary — a stale or partially upgraded install can ship a mismatched catalog
- If wrapping go-plugin directly, add plugins: map[string]plugin.Plugin{"executor": &ExecutorPlugin{}} to the config
Example fix
// before
config := &plugin.ClientConfig{HandshakeConfig: handshake, VersionedPlugins: versionedPlugins}
// after: ensure the executor plugin is registered for the negotiated version
config := &plugin.ClientConfig{
HandshakeConfig: handshake,
VersionedPlugins: map[int]plugin.PluginSet{
1: {"executor": &ExecutorPlugin{}},
},
} Defensive patterns
Strategy: type-guard
Validate before calling
// ensure the client config registers the executor plugin before creating the client
if _, ok := config.Plugins["executor"]; !ok {
return fmt.Errorf("executor plugin not registered in plugin set")
} Type guard
func isExecutorRegistered(cfg *plugin.ClientConfig) bool {
for _, set := range cfg.VersionedPlugins {
if _, ok := set["executor"]; ok { return true }
}
if _, ok := cfg.Plugins["executor"]; ok { return true }
return false
} Try / catch
raw, err := rpcClient.Dispense("executor")
if err != nil {
return fmt.Errorf("dispense executor: %w", err) // inspect: plugin set mismatch, not transient
} Prevention
- Always register {"executor": &ExecutorPlugin{}} in the plugin set for every negotiated version
- Use build-time tests that Dispense("executor") succeeds against the shipped catalog
- Keep launcher and reattach code paths on the same binary version
When it happens
Trigger: newExecutorClient builds a plugin.ClientConfig whose Plugins map lacks the "executor" key, or the plugin set version negotiated differs so the name is absent; can occur in both CreateExecutor and ReattachToExecutor paths.
Common situations: Code changes renaming/omitting the executor entry in the plugin set; a custom build linking a different plugin catalog; version skew between the launcher that wrote the reattach config and the reattaching binary.
Related errors
- error creating rpc client for executor plugin: %v
- unexpected executor rpc type: %T
- no servers
- missing NodeID
- missing AllocID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/7725f5055ff3a625.
Report an issue: GitHub.