hashicorp/nomad · error
task with ID %q already started
Error message
task with ID %q already started
What it means
This error is returned by StartTask when a task with the same ID is already tracked by the driver in its in-memory tasks map. Nomad task IDs are unique per allocation, so this indicates duplicate startup for the same task, most often a race or a client bug that calls StartTask twice. It prevents double-running the same task within the driver.
Source
Thrown at drivers/java/driver.go:434
exec: execImpl,
pid: taskState.Pid,
pluginClient: pluginClient,
taskConfig: taskState.TaskConfig,
procState: drivers.TaskStateRunning,
startedAt: taskState.StartedAt,
exitResult: &drivers.ExitResult{},
logger: d.logger,
}
d.tasks.Set(taskState.TaskConfig.ID, h)
go h.run()
return nil
}
func (d *Driver) StartTask(cfg *drivers.TaskConfig) (handle *drivers.TaskHandle, network *drivers.DriverNetwork, err error) {
if _, ok := d.tasks.Get(cfg.ID); ok {
return nil, nil, fmt.Errorf("task with ID %q already started", cfg.ID)
}
var driverConfig TaskConfig
if err := cfg.DecodeDriverConfig(&driverConfig); err != nil {
return nil, nil, fmt.Errorf("failed to decode driver config: %v", err)
}
if err := driverConfig.validate(); err != nil {
return nil, nil, fmt.Errorf("failed driver config validation: %v", err)
}
if driverConfig.Class == "" && driverConfig.JarPath == "" {
return nil, nil, fmt.Errorf("jar_path or class must be specified")
}
absPath, err := GetAbsolutePath("java")
if err != nil {
return nil, nil, fmt.Errorf("failed to find java binary: %s", err)View on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the task ID is unique per allocation and not reused
- Check whether the task is already running (d.tasks / nomad alloc status) before starting
- Stop the existing task/allocation before starting a new one with the same ID
- If caused by a race or recovery bug, restart the Nomad client and report the issue
Example fix
// before
handle, _, _ := driver.StartTask(cfg) // called twice for same cfg.ID
// after
if _, ok := driver.(*javaDriver).tasks.Get(cfg.ID); !ok {
handle, _, _ = driver.StartTask(cfg)
} Defensive patterns
Strategy: validation
Validate before calling
// ensure unique task IDs before starting
ids := map[string]bool{}
for _, t := range group.Tasks {
if ids[t.Name] { return errors.New("duplicate task id") }
ids[t.Name] = true
} Try / catch
if _, _, err := driver.StartTask(cfg); err != nil {
if strings.Contains(err.Error(), "already started") {
// treat as success or stop the existing task first
}
} Prevention
- Never reuse task IDs across starts; derive them from unique alloc IDs
- Serialize StartTask calls per task to avoid races
- Clean up d.tasks entries when tasks are destroyed
- Let Nomad's driver manager drive starts instead of custom automation
When it happens
Trigger: Calling StartTask twice with a *drivers.TaskConfig whose ID is already present in d.tasks; concurrent starts racing past the Get check; client state restore followed by an explicit start.
Common situations: Driver plugin bugs or custom automation invoking the driver directly; recovery logic replaying starts; test harnesses reusing task IDs without cleanup.
Related errors
- task with ID %q already started
- default_pid_mode must be %q or %q, got %q
- default_ipc_mode must be %q or %q, got %q
- allow_caps configured with capabilities not supported by sys
- pid_mode must be %q or %q, got %q
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/36d76e5477ee372e.
Report an issue: GitHub.