{"record":{"id":"8493d111343c66ba","repo":"hashicorp/nomad","slug":"update-max-parallel-count-is-greater-than-task-gro","errorCode":null,"errorMessage":"Update max parallel count is greater than task group count (%d > %d). A destructive change would result in the simultaneous replacement of all allocations.","messagePattern":"Update max parallel count is greater than task group count \\((.+?) > (.+?)\\)\\. A destructive change would result in the simultaneous replacement of all allocations\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"nomad/structs/structs.go","lineNumber":7647,"sourceCode":"\tif int64(tg.Count) < tg.Scaling.Min && !(j.IsMultiregion() && tg.Count == 0 && j.Region == \"global\") {\n\t\tmErr.Errors = append(mErr.Errors,\n\t\t\tfmt.Errorf(\"Scaling policy invalid: task group count must not be less than minimum count in scaling policy\"))\n\t}\n\n\treturn mErr.ErrorOrNil()\n}\n\n// Warnings returns a list of warnings that may be from dubious settings or\n// deprecation warnings.\nfunc (tg *TaskGroup) Warnings(j *Job) error {\n\tvar mErr multierror.Error\n\n\t// Validate the update strategy\n\tif u := tg.Update; u != nil {\n\t\t// Check the counts are appropriate\n\t\tif tg.Count > 1 && u.MaxParallel > tg.Count && !(j.IsMultiregion() && tg.Count == 0) {\n\t\t\tmErr.Errors = append(mErr.Errors,\n\t\t\t\tfmt.Errorf(\"Update max parallel count is greater than task group count (%d > %d). \"+\n\t\t\t\t\t\"A destructive change would result in the simultaneous replacement of all allocations.\", u.MaxParallel, tg.Count))\n\t\t}\n\t}\n\n\tif tg.MaxClientDisconnect != nil {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"MaxClientDisconnect is deprecated and ignored in favor of Disconnect.LostAfter\"))\n\t}\n\n\tif tg.StopAfterClientDisconnect != nil {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"StopAfterClientDisconnect is deprecated and ignored favor of Disconnect.StopOnClientAfter\"))\n\t}\n\n\tif tg.PreventRescheduleOnLost {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"PreventRescheduleOnLost is deprecated and ignored in favor of Disconnect.Replace\"))\n\t}\n\n\t// Warn about unbounded rescheduling which may cause thrashing if tasks have\n\t// unlimited attempts and a low delay.","sourceCodeStart":7629,"sourceCodeEnd":7665,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L7629-L7665","documentation":"The update strategy's max_parallel exceeds the task group's count (when count > 1), meaning a deployment could replace every allocation at once. Nomad flags this as a warning-class validation error because it defeats rolling-update safety.","triggerScenarios":"Setting `update { max_parallel = N }` where N > tg.Count and the group is not a multiregion group with count 0, e.g. count=2 with max_parallel=5.","commonSituations":"Copy-pasting update blocks with max_parallel=10 into small groups; shrinking a group's count after autoscaling reduced instances while keeping a large max_parallel; canary/stagger values tuned for big fleets applied to dev jobs.","solutions":["Reduce `max_parallel` to be <= the group count (typically 1-3)","Increase the group `count` if a high parallelism rollout is intended","Remove the update block for single-instance/dev groups"],"exampleFix":"// before\ncount = 2\nupdate { max_parallel = 5 min_healthy_time = \"10s\" }\n// after\ncount = 2\nupdate { max_parallel = 1 min_healthy_time = \"10s\" }","handlingStrategy":"validation","validationCode":"if u := g.Update; u != nil && g.Count > 1 && u.MaxParallel > g.Count {\n  return fmt.Errorf(\"max_parallel %d > count %d\", u.MaxParallel, g.Count)\n}","typeGuard":"func safeUpdate(g *api.TaskGroup) bool {\n  return g.Update == nil || g.Count <= 1 || g.Update.MaxParallel <= g.Count\n}","tryCatchPattern":null,"preventionTips":["Cap max_parallel at a fraction of count (e.g. count/2)","Review update blocks when copy-pasting between small and large groups","Treat this warning in CI rather than ignoring `nomad job plan` output"],"tags":["nomad","update-strategy","deployment"],"backgroundTag":"unsafe-rolling-update-config","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"}