{"record":{"id":"aa7410f056feec05","repo":"hashicorp/nomad","slug":"task-q-not-found-in-updated-alloc-aa7410","errorCode":null,"errorMessage":"task %q not found in updated alloc","messagePattern":"task %q not found in updated alloc","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocrunner/taskrunner/service_hook.go","lineNumber":179,"sourceCode":"\n\treturn h.serviceRegWrapper.UpdateWorkload(oldWorkloadServices, newWorkloadServices)\n}\n\nfunc (h *serviceHook) updateHookFields(req *interfaces.TaskUpdateRequest) error {\n\t// Store new updated values out of request\n\tcanary := false\n\tif req.Alloc.DeploymentStatus != nil {\n\t\tcanary = req.Alloc.DeploymentStatus.Canary\n\t}\n\n\tvar networks structs.Networks\n\tif res := req.Alloc.AllocatedResources.Tasks[h.taskName]; res != nil {\n\t\tnetworks = res.Networks\n\t}\n\n\ttask := req.Alloc.LookupTask(h.taskName)\n\tif task == nil {\n\t\treturn fmt.Errorf(\"task %q not found in updated alloc\", h.taskName)\n\t}\n\n\t// Update service hook fields\n\th.taskEnv = req.TaskEnv\n\th.services = task.Services\n\th.networks = networks\n\th.canary = canary\n\th.ports = req.Alloc.AllocatedResources.Shared.Ports\n\n\t// An update may change the service provider, therefore we need to account\n\t// for how namespaces work across providers also.\n\th.providerNamespace = req.Alloc.ServiceProviderNamespaceForTask(h.taskName)\n\n\treturn nil\n}\n\nfunc (h *serviceHook) PreKilling(ctx context.Context, req *interfaces.TaskPreKillRequest, resp *interfaces.TaskPreKillResponse) error {\n\th.mu.Lock()","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocrunner/taskrunner/service_hook.go#L161-L197","documentation":"The taskrunner service hook's Update handler cannot find its task in the updated allocation. When an allocation update arrives, updateHookFields looks up the task by h.taskName via Alloc.LookupTask; a nil result (task removed or renamed in the new alloc) makes the hook fail the update. It is an internal consistency error — the hook state no longer matches the incoming allocation.","triggerScenarios":"Allocation update delivered to a taskrunner whose task was removed from the task group (task stopped/scaled down) or renamed in a job update, so req.Alloc.LookupTask(h.taskName) returns nil during Update.","commonSituations":"Job specification edited to remove or rename a task while allocations were running; a stale/racing update reaching a taskrunner already shutting down; cluster or tooling (e.g. nomad job run of an older job file) overwriting a job with a task set lacking the task.","solutions":["Verify the running job definition still contains the task (nomad job inspect) — restore the task name if it was accidentally removed or renamed in a job update.","Re-run the intended/current job file to resync the allocation with the desired task list.","If the task was intentionally removed, ignore as benign — the allocation will stop; ensure Nomad version is current (race fixes land over time).","Check client logs for a prior stop signal to confirm it is a shutdown race rather than a config regression."],"exampleFix":"// before: job updated removing the task while it was running\ngroup \"web\" { task \"api\" {} }\n// after: keep the task or perform an intentional destructive update\ngroup \"web\" { task \"api\" {} task \"worker\" {} }","handlingStrategy":"validation","validationCode":"// before running an updated job, ensure running tasks still exist in the new spec\nnewTask := func(job *api.Job, group, task string) bool {\n    for _, tg := range job.TaskGroups {\n        if *tg.Name == group {\n            for _, t := range tg.Tasks {\n                if t.Name == task { return true }\n            }\n        }\n    }\n    return false\n}","typeGuard":"func taskInAlloc(alloc *structs.Allocation, taskName string) bool {\n    return alloc != nil && alloc.LookupTask(taskName) != nil\n}","tryCatchPattern":null,"preventionTips":["Treat task removal/rename as a destructive job change; use a new job name or staged rollout.","Inspect the live job (nomad job inspect) before editing to avoid clobbering tasks added by others.","Keep Nomad clients/servers on current patch releases to pick up alloc-update race fixes.","Watch client logs during deployments for hook update failures."],"tags":["nomad","allocrunner","services","allocation-update"],"backgroundTag":"task-not-found-in-allocation","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}