hashicorp/nomad · error

cannot destroy running task

Error message

cannot destroy running task

What it means

DestroyTask removes a task's resources and process. As a safety measure, if the task is still running and force is false, the driver refuses to destroy it and returns this error, preventing accidental loss of a live task.

Source

Thrown at drivers/exec/driver.go:643

	if err := handle.exec.Shutdown(signal, timeout); err != nil {
		if handle.pluginClient.Exited() {
			return nil
		}
		return fmt.Errorf("executor Shutdown failed: %v", err)
	}

	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")
	}

	if !handle.pluginClient.Exited() {
		if err := handle.exec.Shutdown("", 0); err != nil {
			handle.logger.Error("destroying executor failed", "error", err)
		}

		handle.pluginClient.Kill()
	}

	d.tasks.Delete(taskID)
	return nil
}

func (d *Driver) InspectTask(taskID string) (*drivers.TaskStatus, error) {
	handle, ok := d.tasks.Get(taskID)
	if !ok {
		return nil, drivers.ErrTaskNotFound

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Call StopTask first and wait for the task to exit, then call DestroyTask.
  2. If immediate teardown is intended, pass force=true to DestroyTask.
  3. Check task state via TaskStatus/inspect to confirm the task has exited before destroying.

Example fix

// before
err := driver.DestroyTask(taskID, false)
// after
if err := driver.StopTask(taskID, 30*time.Second, "SIGINT"); err != nil {
    handle.logger.Warn("stop failed, forcing destroy", "error", err)
}
err := driver.DestroyTask(taskID, true)
Defensive patterns

Strategy: validation

Validate before calling

status, err := driver.TaskStatus(taskID)
if err != nil { return err }
if status.State == drivers.TaskRunning && !force {
    return fmt.Errorf("task %s still running; stop it first", taskID)
}
return driver.DestroyTask(taskID, force)

Try / catch

if err := driver.DestroyTask(taskID, false); err != nil && strings.Contains(err.Error(), "cannot destroy running task") {
    _ = driver.StopTask(taskID, 30*time.Second, "SIGINT")
    err = driver.DestroyTask(taskID, true)
}

Prevention

When it happens

Trigger: Calling driver.DestroyTask(taskID, false) while handle.IsRunning() is true.

Common situations: Tooling or plugins calling DestroyTask without first stopping the task; a task that failed to shut down during StopTask followed by a non-forced destroy; race between a check and the destroy call.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/db0d1566b1dbdbeb. Report an issue: GitHub.