{"record":{"id":"e7f314f795b9b40b","repo":"hashicorp/nomad","slug":"nomad-can-only-make-v-attempts-in-v-with-initial","errorCode":null,"errorMessage":"Nomad can only make %v attempts in %v with initial delay %v and delay function %q","messagePattern":"Nomad can only make (.+?) attempts in (.+?) with initial delay (.+?) and delay function %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":6723,"sourceCode":"}\n\nfunc isValidDelayFunction(delayFunc string) bool {\n\tfor _, value := range RescheduleDelayFunctions {\n\t\tif value == delayFunc {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (r *ReschedulePolicy) validateDelayParams() error {\n\tok, possibleAttempts, recommendedInterval := r.viableAttempts()\n\tif ok {\n\t\treturn nil\n\t}\n\tvar mErr multierror.Error\n\tif r.DelayFunction == \"constant\" {\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Nomad can only make %v attempts in %v with initial delay %v and \"+\n\t\t\t\"delay function %q\", possibleAttempts, r.Interval, r.Delay, r.DelayFunction))\n\t} else {\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Nomad can only make %v attempts in %v with initial delay %v, \"+\n\t\t\t\"delay function %q, and delay ceiling %v\", possibleAttempts, r.Interval, r.Delay, r.DelayFunction, r.MaxDelay))\n\t}\n\t_ = multierror.Append(&mErr, fmt.Errorf(\"Set the interval to at least %v to accommodate %v attempts\", recommendedInterval.Round(time.Second), r.Attempts))\n\treturn mErr.ErrorOrNil()\n}\n\nfunc (r *ReschedulePolicy) viableAttempts() (bool, int, time.Duration) {\n\tvar possibleAttempts int\n\tvar recommendedInterval time.Duration\n\tvalid := true\n\tswitch r.DelayFunction {\n\tcase \"constant\":\n\t\trecommendedInterval = time.Duration(r.Attempts) * r.Delay\n\t\tif r.Interval < recommendedInterval {\n\t\t\tpossibleAttempts = int(r.Interval / r.Delay)","sourceCodeStart":6705,"sourceCodeEnd":6741,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L6705-L6741","documentation":"ReschedulePolicy.Validate calls viableAttempts() which computes how many retries actually fit in the configured Interval given the Delay, DelayFunction and MaxDelay. If the retry budget (Attempts) cannot be achieved within Interval, this error is thrown for constant delay functions. It tells you the real number of attempts possible so you can correct the policy.","triggerScenarios":"Submitting a job with reschedule.delay_function = \"constant\" where Delay * Attempts > Interval (i.e. possibleAttempts < r.Attempts), and unlimited is false. Example: attempts=5, delay=10m, interval=20m — only 2 attempts fit.","commonSituations":"Users set generous delays but a short interval, expecting all attempts to fire; upgrading Nomad after stricter validation was added; auto-generated policies where interval and delay were configured independently.","solutions":["Increase interval so that interval >= attempts * delay for constant delay functions.","Reduce attempts to the number reported as possibleAttempts in the error.","Reduce the initial delay so all attempts fit in the interval.","Set unlimited: true to skip this accounting check.","Use the recommendedInterval from the companion error to size the interval correctly."],"exampleFix":"// before\nreschedule {\n  attempts = 5\n  interval = \"20m\"\n  delay    = \"10m\"\n  delay_function = \"constant\"\n}\n// after\nreschedule {\n  attempts = 5\n  interval = \"50m\"\n  delay    = \"10m\"\n  delay_function = \"constant\"\n}","handlingStrategy":"validation","validationCode":"func constantDelayViable(p *structs.ReschedulePolicy) error {\n\tif p.DelayFunction != \"constant\" || p.Unlimited {\n\t\treturn nil\n\t}\n\tif need := time.Duration(p.Attempts) * p.Delay; need > p.Interval {\n\t\treturn fmt.Errorf(\"need interval >= %v, have %v\", need, p.Interval)\n\t}\n\treturn nil\n}","typeGuard":"func constantDelayFits(p *structs.ReschedulePolicy) bool {\n\treturn p.Unlimited || p.DelayFunction != \"constant\" || time.Duration(p.Attempts)*p.Delay <= p.Interval\n}","tryCatchPattern":"if err := policy.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"delay function \\\"constant\\\"\") {\n\t\t// enlarge interval or reduce attempts/delay, then retry submit\n\t}\n}","preventionTips":["Ensure interval >= attempts * delay for constant delay functions.","Reuse the recommendedInterval hint from validation output.","Simulate the delay schedule in unit tests for generated policies.","Prefer built-in defaults over hand-tuned aggressive reschedule values."],"tags":["nomad","go","validation","reschedule-policy","configuration"],"backgroundTag":"reschedule-attempts-exceed-interval","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"}