{"record":{"id":"604f1065aebf37bf","repo":"hashicorp/nomad","slug":"unexpected-executor-rpc-type-t","errorCode":null,"errorMessage":"unexpected executor rpc type: %T","messagePattern":"unexpected executor rpc type: %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/shared/executor/utils.go","lineNumber":115,"sourceCode":"\t\treturn nil, nil, err\n\t}\n\treturn exec, pluginClient, nil\n}\n\nfunc newExecutorClient(config *plugin.ClientConfig, logger hclog.Logger) (Executor, *plugin.Client, error) {\n\texecutorClient := plugin.NewClient(config)\n\trpcClient, err := executorClient.Client()\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"error creating rpc client for executor plugin: %v\", err)\n\t}\n\n\traw, err := rpcClient.Dispense(\"executor\")\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"unable to dispense the executor plugin: %v\", err)\n\t}\n\texecutorPlugin, ok := raw.(Executor)\n\tif !ok {\n\t\treturn nil, nil, fmt.Errorf(\"unexpected executor rpc type: %T\", raw)\n\t}\n\treturn executorPlugin, executorClient, nil\n}\n\nfunc processStateToProto(ps *ProcessState) (*proto.ProcessState, error) {\n\ttimestamp, err := ptypes.TimestampProto(ps.Time)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpb := &proto.ProcessState{\n\t\tPid:       int32(ps.Pid),\n\t\tExitCode:  int32(ps.ExitCode),\n\t\tSignal:    int32(ps.Signal),\n\t\tOomKilled: ps.OOMKilled,\n\t\tTime:      timestamp,\n\t}\n\n\treturn pb, nil","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/shared/executor/utils.go#L97-L133","documentation":"Returned when Dispense(\"executor\") succeeded but the returned raw type does not implement the local Executor interface. This indicates the plugin on the other end of the RPC is not the expected executor implementation — a programming/version mismatch rather than an environment failure, since the concrete gRPC client type should satisfy Executor.","triggerScenarios":"The PluginSet entry named \"executor\" dispenses a type other than the executor's ExecutorClient (e.g. wrong plugin registered under the same name, or the Executor interface changed while the generated proto client did not), in CreateExecutor or ReattachToExecutor.","commonSituations":"Mismatched Nomad versions between server-dispatched driver code and client executor binaries; custom forks registering a different plugin under the \"executor\" name; interface drift after regenerating protobuf stubs without updating the wrapper.","solutions":["Check that ExecutorPlugin.New returns a type implementing Executor (e.g. *ExecutorClient) and is registered under \"executor\"","Align client and server Nomad versions — reattach configs and plugin implementations must come from the same build","Regenerate/rebuild proto stubs and recompile so the dispensed client satisfies the current Executor interface","Audit custom plugin set overrides for accidental name collisions on \"executor\""],"exampleFix":"// before: wrong implementation registered under the name\nfunc (p *ExecutorPlugin) New(...) (interface{}, error) { return &OtherClient{}, nil }\n// after\nfunc (p *ExecutorPlugin) New(...) (interface{}, error) { return &ExecutorClient{...}, nil }","handlingStrategy":"type-guard","validationCode":"raw, err := rpcClient.Dispense(\"executor\")\nif err != nil { return nil, nil, err }\nif _, ok := raw.(Executor); !ok {\n    return nil, nil, fmt.Errorf(\"plugin %T does not implement Executor; check build/version alignment\", raw)\n}","typeGuard":"func asExecutor(raw interface{}) (Executor, bool) {\n    e, ok := raw.(Executor)\n    return e, ok\n}","tryCatchPattern":"executor, ok := raw.(Executor)\nif !ok {\n    // log the concrete type to diagnose version skew; do not proceed\n    return nil, nil, fmt.Errorf(\"unexpected executor rpc type: %T\", raw)\n}","preventionTips":["Add a unit test asserting ExecutorPlugin.New returns a value satisfying Executor","Regenerate proto stubs and recompile in the same change that alters the Executor interface","Pin client/server to the same release channel"],"tags":["go-plugin","type-assertion","rpc","nomad"],"backgroundTag":"type-assertion-failed","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"}