hashicorp/nomad · error
cannot destroy running task
Error message
cannot destroy running task
What it means
Returned by the mock driver's DestroyTask when the task handle is still running and force was not set; the mock driver refuses to destroy a live task unless destruction is forced.
Source
Thrown at drivers/mock/driver.go:576
select {
case <-h.waitCh:
d.logger.Debug("not killing task: already exited", "task_name", h.taskConfig.Name)
case <-time.After(h.killAfter):
d.logger.Debug("killing task due to kill_after", "task_name", h.taskConfig.Name)
h.kill()
}
return nil
}
func (d *Driver) DestroyTask(taskID string, force bool) error {
handle, ok := d.tasks.Get(taskID)
if !ok {
return drivers.ErrTaskNotFound
}
if handle.IsRunning() && !force {
return fmt.Errorf("cannot destroy running task")
}
d.tasks.Delete(taskID)
return nil
}
func (d *Driver) InspectTask(taskID string) (*drivers.TaskStatus, error) {
h, ok := d.tasks.Get(taskID)
if !ok {
return nil, drivers.ErrTaskNotFound
}
return h.TaskStatus(), nil
}
func (d *Driver) TaskStats(ctx context.Context, taskID string, interval time.Duration) (<-chan *drivers.TaskResourceUsage, error) {
ch := make(chan *drivers.TaskResourceUsage)View on GitHub (pinned to 482b49bf1a)
Solutions
- Stop the task first (StopTask or kill the handle) and wait for it to exit, then call DestroyTask.
- Pass force=true to DestroyTask if you intentionally want to discard a running task.
- Check handle.IsRunning() before destroying and poll until it returns false.
Example fix
// before
err := drv.DestroyTask(ctx, id, false)
// after
if h, _ := drv.InspectTask(ctx, id); h.State == drivers.TaskRunning {
_ = drv.StopTask(ctx, id, time.Second*30)
}
err := drv.DestroyTask(ctx, id, false) Defensive patterns
Strategy: type-guard
Validate before calling
st, err := drv.InspectTask(ctx, taskID)
if err != nil { return err }
canDestroy := st.State != drivers.TaskRunning Type guard
func canDestroy(st *drivers.TaskStatus) bool { return st != nil && st.State != drivers.TaskRunning } Try / catch
err := drv.DestroyTask(ctx, id, false)
if err != nil && strings.Contains(err.Error(), "cannot destroy running task") {
_ = drv.StopTask(ctx, id, 30*time.Second)
err = drv.DestroyTask(ctx, id, false)
} Prevention
- Always StopTask and wait for a non-running state before DestroyTask.
- Only pass force=true when you accept losing a running task's data.
When it happens
Trigger: Calling DestroyTask(ctx, taskID, false) while handle.IsRunning() is true — the task's run goroutine has not finished or been killed.
Common situations: Application code calling DestroyTask directly without first StopTask/kill; race between a test teardown and a still-exiting mock task.
Related errors
- no exec command is configured
- handle cannot be nil
- cannot destroy running task
- handle cannot be nil
- failed to decode task state from handle: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/38d25918e6bae161.
Report an issue: GitHub.