{"record":{"id":"104f54156422f628","repo":"hashicorp/nomad","slug":"unable-to-find-task-group-in-the-job-summary-v","errorCode":null,"errorMessage":"unable to find task group in the job summary: %v","messagePattern":"unable to find task group in the job summary: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store.go","lineNumber":6087,"sourceCode":"\t\tif rawJob == nil {\n\t\t\treturn nil\n\t\t}\n\n\t\treturn fmt.Errorf(\"job summary for job %q in namespace %q is not present\", alloc.JobID, alloc.Namespace)\n\t}\n\n\t// Get a copy of the existing summary\n\tjobSummary := summaryRaw.(*structs.JobSummary).Copy()\n\n\t// Not updating the job summary because the allocation doesn't belong to the\n\t// currently registered job\n\tif jobSummary.CreateIndex != alloc.Job.CreateIndex {\n\t\treturn nil\n\t}\n\n\ttgSummary, ok := jobSummary.Summary[alloc.TaskGroup]\n\tif !ok {\n\t\treturn fmt.Errorf(\"unable to find task group in the job summary: %v\", alloc.TaskGroup)\n\t}\n\n\tsummaryChanged := false\n\tif existingAlloc == nil {\n\t\tswitch alloc.DesiredStatus {\n\t\tcase structs.AllocDesiredStatusStop, structs.AllocDesiredStatusEvict:\n\t\t\ts.logger.Error(\"new allocation inserted into state store with bad desired status\",\n\t\t\t\t\"alloc_id\", alloc.ID, \"desired_status\", alloc.DesiredStatus)\n\t\t}\n\t\tswitch alloc.ClientStatus {\n\t\tcase structs.AllocClientStatusPending:\n\t\t\ttgSummary.Starting += 1\n\t\t\tif tgSummary.Queued > 0 {\n\t\t\t\ttgSummary.Queued -= 1\n\t\t\t}\n\t\t\tsummaryChanged = true\n\t\tcase structs.AllocClientStatusRunning, structs.AllocClientStatusFailed,\n\t\t\tstructs.AllocClientStatusComplete:","sourceCodeStart":6069,"sourceCodeEnd":6105,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store.go#L6069-L6105","documentation":"This error is thrown by Nomad's StateStore while updating a job's summary during allocation changes. The code looks up the allocation's task group in the job's summary map (jobSummary.Summary); if the key is absent, the state store cannot apply the allocation change to the group's counts, so the transaction is aborted with this error. It indicates internal state inconsistency: the allocation references a task group the job summary does not track.","triggerScenarios":"Upserting an allocation whose alloc.JobSummary.CreateIndex matches the job summary's CreateIndex (so the summary is considered current) but whose alloc.TaskGroup is not a key in jobSummary.Summary — e.g. state reconstructed from a snapshot/restore missing the group entry, or an allocation written for a task group removed/renamed in the job spec.","commonSituations":"Restoring Nomad state from a backup where the job_summary table predates a task-group rename; applying an alloc snapshot out of order; raft log replay after manual state surgery; bugs in job update paths that replace Summary map contents without the group key.","solutions":["Verify alloc.TaskGroup exactly matches the task group name in the job spec (names are case-sensitive)","Re-snapshot or repair state: ensure the job_summary entry contains a Summary entry for every task group in the job before replaying allocs","Check that the job was updated through the normal Job.Register path so the summary is regenerated for renamed/added groups","If seen after a restore, re-run nomad operator raft / state restore from a consistent snapshot"],"exampleFix":"// before (alloc for a group missing from summary)\nalloc.TaskGroup = \"web-v2\" // job spec has \"web\"\n// after\nalloc.TaskGroup = \"web\" // must match the group name registered in the job summary","handlingStrategy":"validation","validationCode":"// Before writing an alloc (tooling/restore scripts): ensure the summary has the group\n// (via Nomad API: GET /v1/job/<id>/summary)\nconst summary = await nomad.get(`/v1/job/${jobID}/summary`);\nif (!summary.Summary[alloc.TaskGroup]) {\n  throw new Error(`task group ${alloc.TaskGroup} missing from job ${jobID} summary; re-register the job first`);\n}","typeGuard":"function hasTaskGroupSummary(summary, tg) {\n  return summary && summary.Summary && Object.prototype.hasOwnProperty.call(summary.Summary, tg);\n}","tryCatchPattern":"try {\n  await nomad.allocsUpdate(alloc);\n} catch (e) {\n  if (String(e).includes('unable to find task group in the job summary')) {\n    // re-register the job to rebuild summaries, then retry\n    await nomad.post(`/v1/job/${alloc.JobID}`, jobSpec);\n    await nomad.allocsUpdate(alloc);\n  } else throw e;\n}","preventionTips":["Always register jobs through the normal Job.Register API so summaries stay in sync","Never hand-edit or partially restore job_summary state","Keep alloc.TaskGroup strings exactly matching the job spec group names","After task-group renames, expect new allocs, not reuse of old alloc objects"],"tags":["nomad","state-store","job-summary","raft"],"backgroundTag":"job-summary-task-group-missing","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"}