hashicorp/nomad · error

cannot destroy running task

Error message

cannot destroy running task

What it means

DestroyTask cleans up a finished task's resources. raw_exec refuses to destroy a task whose handle still reports IsRunning() unless force=true, returning 'cannot destroy running task'. This protects live processes from being torn down accidentally.

Source

Thrown at drivers/rawexec/driver.go:556

	}

	// Wait for handle to finish
	<-handle.doneCh

	// Kill executor
	handle.pluginClient.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")
	}

	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. Wait for the task to fully exit (StopTask's doneCh / handle done) before calling DestroyTask
  2. Call DestroyTask with force=true if you intend to kill it regardless
  3. Check client logs to see why the task is still considered running (executor hung? signal ignored?)
  4. Restart the client if the handle is stuck running though the process is gone

Example fix

// before
err := driver.DestroyTask(taskID, false)
// after
if err := driver.StopTask(taskID, 30*time.Second, "SIGTERM"); err != nil { log.Warn(err) }
err := driver.DestroyTask(taskID, true)
Defensive patterns

Strategy: validation

Validate before calling

if handle.IsRunning() {
    // stop first or use force
}
driver.DestroyTask(taskID, force)

Prevention

When it happens

Trigger: Calling DestroyTask(taskID, false) (force=false) on a task whose handle is still marked running — the executor has not reported exit yet.

Common situations: Scripts/garbage collectors calling DestroyTask too early after StopTask; tasks that failed to stop within kill_timeout so the handle still appears running; GC racing with a slow-shutting task.

Related errors


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