{"record":{"id":"95bf6078b3309973","repo":"hashicorp/nomad","slug":"failed-evaluate-job-w","errorCode":null,"errorMessage":"Failed evaluate job: %w","messagePattern":"Failed evaluate job: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/job_restart.go","lineNumber":966,"sourceCode":"\t}\n\n\t// Stop allocation and wait for its replacement to be running or for a\n\t// blocked evaluation that prevents placements for this task group to\n\t// happen.\n\tresp, err := c.client.Allocations().Stop(&api.Allocation{ID: alloc.ID}, q)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Failed to stop allocation: %w\", err)\n\t}\n\n\t// Allocations for system jobs do not get replaced by the scheduler after\n\t// being stopped, so an eval is needed to trigger the reconciler.\n\tif alloc.isSystemJob() {\n\t\topts := api.EvalOptions{\n\t\t\tForceReschedule: true,\n\t\t}\n\t\t_, _, err := c.client.Jobs().EvaluateWithOpts(*alloc.Job.ID, opts, nil)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Failed evaluate job: %w\", err)\n\t\t}\n\t}\n\n\t// errCh receives an error if anything goes wrong or nil when the\n\t// replacement allocation is running.\n\t// Use a buffered channel to prevent both goroutine from blocking trying to\n\t// send a result back.\n\terrCh := make(chan error, 1)\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\t// Pass the LastIndex from the Stop() call to only monitor data that was\n\t// created after the Stop() call.\n\tgo c.monitorPlacementFailures(ctx, alloc, resp.LastIndex, errCh)\n\tgo c.monitorReplacementAlloc(ctx, alloc, errCh)\n\n\t// This process may take a while, so ping user from time to time to\n\t// indicate the command is still alive.","sourceCodeStart":948,"sourceCodeEnd":984,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/job_restart.go#L948-L984","documentation":"For system jobs, stopped allocs are not replaced automatically, so stopAlloc forces an evaluation via Jobs().EvaluateWithOpts with ForceReschedule. If that call errors, it is wrapped as 'Failed evaluate job: <cause>'.","triggerScenarios":"EvaluateWithOpts fails while restarting a system-job alloc — agent unreachable, job ID stale (job deleted), or ACL token lacking job-submit/evaluate permission.","commonSituations":"Job was deleted or purged while a restart of its allocs was in progress; network interruption to the Nomad API; token without submit-job ACL capability.","solutions":["Verify the job still exists (nomad job status <job-id>)","Check connectivity to the Nomad agent / NOMAD_ADDR","Ensure the ACL token can submit evaluations for the job","Re-run the restart command after restoring API access"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"job, _, err := client.Jobs().Info(*alloc.Job.ID, nil)\nif err != nil {\n    return fmt.Errorf(\"job %s unavailable before evaluate: %w\", *alloc.Job.ID, err)\n}","typeGuard":null,"tryCatchPattern":"_, _, err := client.Jobs().EvaluateWithOpts(jobID, opts, nil)\nif err != nil {\n    var apiErr error\n    if errors.As(err, &apiErr) && strings.Contains(err.Error(), \"403\") {\n        return fmt.Errorf(\"ACL token lacks submit-job permission: %w\", err)\n    }\n    return fmt.Errorf(\"evaluate failed, check agent connectivity: %w\", err)\n}","preventionTips":["Confirm the job still exists before restarting its allocs","Verify ACL submit-job capability","Check NOMAD_ADDR connectivity before long operations"],"tags":["nomad","api","evaluation","system-job"],"backgroundTag":"job-evaluate-failed","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"}