hashicorp/nomad · error

task %q not found in updated alloc

Error message

task %q not found in updated alloc

What it means

scriptCheckHook.Update refreshes the hook's cached alloc, task, env, and Consul namespaces whenever the allocation is updated. It looks up the task by the hook's stored task name using req.Alloc.LookupTask; if the updated allocation no longer contains a task with that name, the update cannot proceed and this error is returned.

Source

Thrown at client/allocrunner/taskrunner/script_check_hook.go:134

		h.logger.Debug("driver doesn't support script checks")
		return nil
	}
	h.driverExec = req.DriverExec
	h.taskEnv = req.TaskEnv

	return h.upsertChecks()
}

// Updated implements interfaces.TaskUpdateHook. It creates new
// script checks with the current task context (driver and env and possibly
// new structs.Task), and starts up the scripts.
func (h *scriptCheckHook) Update(ctx context.Context, req *interfaces.TaskUpdateRequest, _ *interfaces.TaskUpdateResponse) error {
	h.mu.Lock()
	defer h.mu.Unlock()

	task := req.Alloc.LookupTask(h.task.Name)
	if task == nil {
		return fmt.Errorf("task %q not found in updated alloc", h.task.Name)
	}
	h.alloc = req.Alloc
	h.task = task
	h.taskEnv = req.TaskEnv
	h.groupConsulNamespace = req.Alloc.ConsulNamespace()
	h.taskConsulNamespace = req.Alloc.ConsulNamespaceForTask(task.Name)

	return h.upsertChecks()
}

func (h *scriptCheckHook) upsertChecks() error {
	// Create new script checks struct with new task context
	oldScriptChecks := h.scripts
	h.scripts = h.newScriptChecks()

	// Run new or replacement scripts
	for id, script := range h.scripts {
		// If it's already running, cancel and replace

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure updated job specs keep the same task name; if removing a task, let the Stop path (not Update) handle it
  2. Check that the allocation being passed in Update actually corresponds to the same task runner/group
  3. Diff the job before/after (`nomad job inspect`) to find where the task name changed
  4. If writing tooling/tests that mutate allocs, always preserve the task entry that hooks reference

Example fix

// before
update := &api.Job{Name: &jobName, TaskGroups: []*api.TaskGroup{{Name: &tgName}}} // task dropped
// after: keep the task entry so Update can find it
update := &api.Job{Name: &jobName, TaskGroups: []*api.TaskGroup{{
    Name: &tgName,
    Tasks: append(newTasks, existingTask), // task with script checks preserved
}}}
Defensive patterns

Strategy: validation

Validate before calling

// caller-side check before invoking Update
func canUpdate(h *scriptCheckHook, alloc *structs.Allocation) bool {
    return alloc != nil && alloc.LookupTask(h.task.Name) != nil
}

Type guard

func taskExists(alloc *structs.Allocation, name string) bool {
    return alloc.LookupTask(name) != nil
}

Try / catch

if err := hook.Update(ctx, req, resp); err != nil {
    if strings.Contains(err.Error(), "not found in updated alloc") {
        // alloc no longer has this task; skip update, rely on Stop
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: An updated allocation (from a job spec change or rescheduling diff) omits or renames the task that this script_check_hook was created for. Update is called by the task runner on alloc updates; LookupTask(h.task.Name) returns nil and Update returns this error without mutating any hook state.

Common situations: A `nomad job stop`/job edit removes or renames a task in a group while script checks are attached; a misapplied job spec diff drops a task; tooling that synthesizes modified allocations (tests, diff appliers) produces an alloc missing the task; races where Update arrives for an alloc of a different task version.

Related errors


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