{"record":{"id":"80b6fae3018da2a7","repo":"hashicorp/nomad","slug":"nomad-can-t-restart-the-taskgroup-v-times-in-an-i","errorCode":null,"errorMessage":"Nomad can't restart the TaskGroup %v times in an interval of %v with a delay of %v","messagePattern":"Nomad can't restart the TaskGroup (.+?) times in an interval of (.+?) with a delay of (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":6583,"sourceCode":"func (r *RestartPolicy) Validate() error {\n\tvar mErr multierror.Error\n\tswitch r.Mode {\n\tcase RestartPolicyModeDelay, RestartPolicyModeFail:\n\tdefault:\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Unsupported restart mode: %q\", r.Mode))\n\t}\n\n\t// Check for ambiguous/confusing settings\n\tif r.Attempts == 0 && r.Mode != RestartPolicyModeFail {\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Restart policy %q with %d attempts is ambiguous\", r.Mode, r.Attempts))\n\t}\n\n\tif r.Interval.Nanoseconds() < RestartPolicyMinInterval.Nanoseconds() {\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Interval can not be less than %v (got %v)\", RestartPolicyMinInterval, r.Interval))\n\t}\n\tif time.Duration(r.Attempts)*r.Delay > r.Interval {\n\t\t_ = multierror.Append(&mErr,\n\t\t\tfmt.Errorf(\"Nomad can't restart the TaskGroup %v times in an interval of %v with a delay of %v\", r.Attempts, r.Interval, r.Delay))\n\t}\n\treturn mErr.ErrorOrNil()\n}\n\nfunc NewRestartPolicy(jobType string) *RestartPolicy {\n\tswitch jobType {\n\tcase JobTypeService, JobTypeSystem:\n\t\trp := DefaultServiceJobRestartPolicy\n\t\treturn &rp\n\tcase JobTypeBatch:\n\t\trp := DefaultBatchJobRestartPolicy\n\t\treturn &rp\n\t}\n\treturn nil\n}\n\nconst ReschedulePolicyMinInterval = 15 * time.Second\nconst ReschedulePolicyMinDelay = 1 * time.Second","sourceCodeStart":6565,"sourceCodeEnd":6601,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L6565-L6601","documentation":"RestartPolicy.Validate() requires that attempts * delay fit within interval. If the product of the restart attempts and the delay between them exceeds the interval, Nomad could not physically perform the configured restarts in the window, so the policy is rejected as mathematically impossible.","triggerScenarios":"A restart block where time.Duration(attempts) * delay > interval, e.g. attempts = 5, delay = \"10m\", interval = \"30m\" (50m > 30m).","commonSituations":"Tuning attempts upward after lowering interval, or setting a long delay for backoff without recomputing the interval; very common after scaling attempts for flaky services.","solutions":["Increase interval so it is >= attempts * delay.","Reduce attempts or delay until the product fits the interval.","Validate the arithmetic: e.g. attempts=5, delay=15s needs interval >= 75s."],"exampleFix":"// before\nrestart {\n  interval = \"30m\"\n  attempts = 5\n  delay    = \"10m\"\n}\n// after\nrestart {\n  interval = \"1h\"\n  attempts = 5\n  delay    = \"10m\"\n}","handlingStrategy":"validation","validationCode":"if rp != nil && time.Duration(rp.Attempts)*rp.Delay > rp.Interval {\n    return fmt.Errorf(\"attempts*delay (%v) exceeds interval (%v)\", time.Duration(rp.Attempts)*rp.Delay, rp.Interval)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Recompute interval whenever attempts or delay changes.","Assert attempts*delay <= interval in policy-generation tests.","Prefer defaults from NewRestartPolicy which satisfy the constraint."],"tags":["nomad","validation","duration","restart-policy"],"backgroundTag":"invalid-config-combination","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"}