{"record":{"id":"af84754f13ea67c9","repo":"hashicorp/nomad","slug":"failed-to-retrieve-allocation-q-w","errorCode":null,"errorMessage":"Failed to retrieve allocation %q: %w","messagePattern":"Failed to retrieve allocation %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/job_restart.go","lineNumber":1076,"sourceCode":"// Returns an error in errCh if anything goes wrong or nil when the new\n// allocation is running.\nfunc (c *JobRestartCommand) monitorReplacementAlloc(\n\tctx context.Context,\n\tallocStub AllocationListStubWithJob,\n\terrCh chan<- error,\n) {\n\tcurrentAllocID := allocStub.ID\n\tq := &api.QueryOptions{WaitIndex: 1}\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tdefault:\n\t\t}\n\n\t\talloc, qm, err := c.client.Allocations().Info(currentAllocID, q)\n\t\tif err != nil {\n\t\t\terrCh <- fmt.Errorf(\"Failed to retrieve allocation %q: %w\", limit(currentAllocID, c.length), err)\n\t\t\treturn\n\t\t}\n\n\t\t// Follow replacement allocations. We expect the original allocation to\n\t\t// be replaced, but the replacements may be themselves replaced in\n\t\t// cases such as the allocation failing.\n\t\tif alloc.NextAllocation != \"\" {\n\t\t\tc.Ui.Output(fmt.Sprintf(\n\t\t\t\t\"    %s: Allocation %q replaced by %[3]q, waiting for %[3]q to start running\",\n\t\t\t\tformatTime(time.Now()),\n\t\t\t\tlimit(alloc.ID, c.length),\n\t\t\t\tlimit(alloc.NextAllocation, c.length),\n\t\t\t))\n\t\t\tcurrentAllocID = alloc.NextAllocation\n\n\t\t\t// Reset the blocking query so the Info() API call returns the new\n\t\t\t// allocation immediately.\n\t\t\tq.WaitIndex = 1","sourceCodeStart":1058,"sourceCodeEnd":1094,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/job_restart.go#L1058-L1094","documentation":"This error is raised by the `nomad job restart` command when its background watcher (monitorReplacementAlloc) fails to fetch info about the allocation it is tracking via the Nomad HTTP API (Allocations().Info). The original API error (auth failure, allocation not found, connectivity problem) is wrapped with %w so the underlying cause is preserved. It is emitted on an error channel and surfaced to the user as the command's failure reason.","triggerScenarios":"Allocations().Info(currentAllocID, q) returns an error while the command polls for the replacement allocation: the allocation was GC'd out of Nomad's state store, the agent/HTTP address is unreachable, the ACL token lacks alloc:lifecycle or namespace-scoped read on the allocation, or the query options (namespace/region) are wrong.","commonSituations":"Restarting a job whose stopped allocation has already been garbage collected; running the CLI against a different cluster/namespace after a context switch; expired or insufficient ACL token (token cannot read the target namespace's allocations); Nomad agent restarted or network partition mid-restart.","solutions":["Verify the allocation still exists: nomad alloc status <alloc-id>; if it was GC'd, rerun nomad job restart on the job instead of a specific allocation.","Confirm the CLI targets the right cluster/namespace: check NOMAD_ADDR, NOMAD_NAMESPACE, NOMAD_REGION env vars and the -namespace/-region flags.","Check ACL permissions: the token needs allocation read access (alloc:lifecycle / namespace = read-alloc) in the target namespace; run nomad acl token self.","Test connectivity to the agent (curl $NOMAD_ADDR/v1/agent/health) and rerun the command if it was a transient network error.","If the wrapped cause is allocation not found after rescheduling, let the command follow the new allocation ID automatically or restart the whole job with -job."],"exampleFix":"// before\nclient := api.NewClient(api.DefaultConfig()) // wrong address / namespace\nalloc, _, err := client.Allocations().Info(id, nil)\n// after\ncfg := api.DefaultConfig()\ncfg.Namespace = \"default\" // match the allocation's namespace\nclient := api.NewClient(cfg)\nalloc, _, err := client.Allocations().Info(id, &api.QueryOptions{Namespace: \"default\"})\nif err != nil && strings.Contains(err.Error(), \"not found\") {\n    // allocation GC'd: fall back to restarting the job instead\n}","handlingStrategy":"try-catch","validationCode":"// check allocation exists and token works before running the restart\nresp, err := http.Get(addr + \"/v1/allocation/\" + allocID)\nif err != nil || resp.StatusCode == 403 {\n    // fix NOMAD_ADDR / ACL token first\n}","typeGuard":"func isNotFound(err error) bool {\n    return err != nil && strings.Contains(strings.ToLower(err.Error()), \"not found\")\n}","tryCatchPattern":"if err := cmd.Run(); err != nil {\n    var apiErr *api.StatusError\n    if errors.As(err, &apiErr) && apiErr.StatusCode == 404 {\n        // allocation GC'd: fall back to `nomad job restart <job>`\n    } else if isTransient(err) {\n        // retry with backoff\n    }\n}","preventionTips":["Pin NOMAD_ADDR/NOMAD_NAMESPACE/NOMAD_REGION per environment in scripts or wrapper scripts.","Use ACL tokens with allocation read scope for restart automation.","Check nomad alloc status before targeting a specific allocation; avoid allocations pending GC.","Retry transient API failures with backoff instead of aborting the restart."],"tags":["nomad","cli","api-client","allocation"],"backgroundTag":"allocation-not-found","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"}