hashicorp/nomad · error
unable to create executor config: %v
Error message
unable to create executor config: %v
What it means
CreateExecutor launches the executor as a Nomad executor plugin subprocess and must serialize the ExecutorConfig to JSON to pass it to the child. This error wraps a json.Marshal failure of *ExecutorConfig, meaning the config could not be encoded (e.g. unsupported field types such as channels, funcs, or custom marshaling errors).
Source
Thrown at drivers/shared/executor/utils.go:41
// searching for an available port
ExecutorDefaultMaxPort = 14512
// ExecutorDefaultMinPort is the default min port used by the executor for
// searching for an available port
ExecutorDefaultMinPort = 14000
)
// CreateExecutor launches an executor plugin and returns an instance of the
// Executor interface
func CreateExecutor(
logger hclog.Logger,
driverConfig *base.ClientDriverConfig,
executorConfig *ExecutorConfig,
) (Executor, *plugin.Client, error) {
c, err := json.Marshal(executorConfig)
if err != nil {
return nil, nil, fmt.Errorf("unable to create executor config: %v", err)
}
bin, err := os.Executable()
if err != nil {
return nil, nil, fmt.Errorf("unable to find the nomad binary: %v", err)
}
p := &ExecutorPlugin{
logger: logger,
fsIsolation: executorConfig.FSIsolation,
compute: driverConfig.Topology.Compute(),
}
config := &plugin.ClientConfig{
HandshakeConfig: base.Handshake,
Plugins: map[string]plugin.Plugin{"executor": p},
Cmd: exec.Command(bin, "executor", string(c)),
AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
Logger: logger.Named("executor"),View on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect the wrapped %v cause to find the offending field type
- Remove or pre-convert unserializable fields (funcs, channels) in the ExecutorConfig before calling CreateExecutor
- Add valid json tags and ensure all embedded types implement correct JSON encoding
- Test config serialization in unit tests before launching the executor plugin
Example fix
// before cfg.FSIsolation = someFuncValue // unserializable exec, _, _ := CreateExecutor(logger, driverCfg, cfg) // after cfg.IsolationKind = "chroot" // serializable string exec, _, err := CreateExecutor(logger, driverCfg, cfg)
Defensive patterns
Strategy: validation
Validate before calling
if _, err := json.Marshal(executorConfig); err != nil { fix config fields before CreateExecutor } Try / catch
exec, _, err := executor.CreateExecutor(logger, drvCfg, cfg)
if err != nil && strings.Contains(err.Error(), "unable to create executor config") {
return fmt.Errorf("config not serializable: %w", err)
} Prevention
- Keep ExecutorConfig JSON-serializable (no funcs/channels)
- Unit-test config marshaling before plugin launch
- Use json tags on all config fields
When it happens
Trigger: Calling executor.CreateExecutor with an ExecutorConfig containing fields that json.Marshal cannot encode (function values, channels, cyclic structures, or a custom MarshalJSON that errors).
Common situations: Driver authors embedding non-serializable values into ExecutorConfig custom fields; version drift where a config struct gained an unserializable field; mismanaged struct tags on forked configs.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- error marshaling volume pramaters: %w
- failed to marshal json from Topic: %s, Type: %s, Err: %w
- could not serialize our own error: %v
- [✘] Role could not be interpolated with args: %w
- auth method could not be interpolated with args: %w
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/52cf78a35c521d66.
Report an issue: GitHub.