{"record":{"id":"7e34ea73d2a7f7c9","repo":"hashicorp/nomad","slug":"task-q-not-started-yet","errorCode":null,"errorMessage":"task %q not started yet.","messagePattern":"task %q not started yet\\.","errorType":"http","errorClass":null,"httpStatus":404,"severity":"warning","filePath":"client/alloc_endpoint.go","lineNumber":359,"sourceCode":"\n\tallocState, err := a.c.GetAllocState(req.AllocID)\n\tif err != nil {\n\t\tcode := new(int64(500))\n\t\tif nstructs.IsErrUnknownAllocation(err) {\n\t\t\tcode = new(int64(404))\n\t\t}\n\n\t\treturn code, err\n\t}\n\n\t// Check that the task is there\n\ttaskState := allocState.TaskStates[req.Task]\n\tif taskState == nil {\n\t\treturn new(int64(400)), fmt.Errorf(\"unknown task name %q\", req.Task)\n\t}\n\n\tif taskState.StartedAt.IsZero() {\n\t\treturn new(int64(404)), fmt.Errorf(\"task %q not started yet.\", req.Task)\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\th := ar.GetTaskExecHandler(req.Task)\n\tif h == nil {\n\t\treturn new(int64(404)), fmt.Errorf(\"task %q is not running.\", req.Task)\n\t}\n\n\terr = h(ctx, req.Cmd, req.Tty, newExecStream(decoder, encoder))\n\tif err != nil {\n\t\tcode := new(int64(500))\n\t\treturn code, err\n\t}\n\n\treturn nil, nil\n}","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/alloc_endpoint.go#L341-L377","documentation":"execImpl checks that the task not only exists but has actually started (taskState.StartedAt is non-zero) before wiring up the exec stream. If the task exists in the allocation but has not yet been started by the client runner, the endpoint returns HTTP 404 with this message. The task is known but not yet runnable.","triggerScenarios":"Invoking exec immediately after the allocation is placed but before the task process launches (image pull, driver startup, etc.), or exec'ing a task stuck in pending state after a restart/reschedule.","commonSituations":"CI scripts that run `nomad alloc exec` immediately after `nomad job run` without waiting for the allocation to become running; slow container image downloads; tasks waiting on vault tokens or consul health before start.","solutions":["Wait until `nomad alloc status <alloc-id>` shows the task as running before exec'ing","Poll the allocation/task state via the API until StartedAt is set","Retry the exec command with backoff after placement","Investigate why the task has not started (driver errors, image pull failures, template blocking)"],"exampleFix":"// before\nclient.Exec(allocID, \"web\", []string{\"sh\"}) // immediately after job run\n// after\nfor {\n  alloc, _, _ := client.Allocations().Info(allocID, nil)\n  ts := alloc.TaskStates[\"web\"]\n  if ts != nil && !ts.StartedAt.IsZero() { break }\n  time.Sleep(time.Second)\n}\nclient.Exec(allocID, \"web\", []string{\"sh\"})","handlingStrategy":"retry","validationCode":"alloc, _, _ := client.Allocations().Info(allocID, nil)\nts := alloc.TaskStates[taskName]\nready := ts != nil && !ts.StartedAt.IsZero()","typeGuard":"func taskStarted(alloc *api.Allocation, task string) bool {\n  ts := alloc.TaskStates[task]\n  return ts != nil && !ts.StartedAt.IsZero()\n}","tryCatchPattern":"var code int64\nfor i := 0; i < 10; i++ {\n  code, err = client.Allocations().Exec(ctx, alloc, taskName, tty, false, cmd, stdin, stdout, stderr, nil, nil)\n  if err == nil || code != 404 || !strings.Contains(fmt.Sprint(err), \"not started yet\") { break }\n  time.Sleep(2 * time.Second)\n}","preventionTips":["Wait for task state Running before exec (poll alloc info)","Use `nomad job dispatch`-style readiness gates in CI","Add backoff-retry around exec after fresh deployment"],"tags":["nomad","exec","race-condition","timing"],"backgroundTag":"task-not-started","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"}