{"record":{"id":"7f82ea3b2e04971f","repo":"hashicorp/nomad","slug":"interval-cannot-be-less-than-v-got-v","errorCode":null,"errorMessage":"Interval cannot be less than %v (got %v)","messagePattern":"Interval cannot be less than (.+?) \\(got (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":6693,"sourceCode":"\t}\n\n\t// Validate MaxDelay if not using linear delay progression\n\tif r.DelayFunction != \"constant\" {\n\t\tif r.MaxDelay.Nanoseconds() < ReschedulePolicyMinDelay.Nanoseconds() {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Max Delay cannot be less than %v (got %v)\", ReschedulePolicyMinDelay, r.Delay))\n\t\t\tdelayPreCheck = false\n\t\t}\n\t\tif r.MaxDelay < r.Delay {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Max Delay cannot be less than Delay %v (got %v)\", r.Delay, r.MaxDelay))\n\t\t\tdelayPreCheck = false\n\t\t}\n\n\t}\n\n\t// Validate Interval and other delay parameters if attempts are limited\n\tif !r.Unlimited {\n\t\tif r.Interval.Nanoseconds() < ReschedulePolicyMinInterval.Nanoseconds() {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Interval cannot be less than %v (got %v)\", ReschedulePolicyMinInterval, r.Interval))\n\t\t}\n\t\tif !delayPreCheck {\n\t\t\t// We can't cross validate the rest of the delay params if delayPreCheck fails, so return early\n\t\t\treturn mErr.ErrorOrNil()\n\t\t}\n\t\tcrossValidationErr := r.validateDelayParams()\n\t\tif crossValidationErr != nil {\n\t\t\t_ = multierror.Append(&mErr, crossValidationErr)\n\t\t}\n\t}\n\treturn mErr.ErrorOrNil()\n}\n\nfunc isValidDelayFunction(delayFunc string) bool {\n\tfor _, value := range RescheduleDelayFunctions {\n\t\tif value == delayFunc {\n\t\t\treturn true\n\t\t}","sourceCodeStart":6675,"sourceCodeEnd":6711,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L6675-L6711","documentation":"ReschedulePolicy.Validate rejects a reschedule policy whose Interval is below ReschedulePolicyMinInterval. Nomad enforces a minimum interval so that the bounded retry budget (Attempts within Interval) is meaningful; a shorter interval would make the attempt accounting meaningless. The error is appended to a multierror and returned from job/task-group validation, typically surfaced on job submission or plan.","triggerScenarios":"Submitting a job whose task_group.reschedule policy has interval set below the minimum (e.g. interval: \"10s\" when the minimum is 15m) while unlimited is false. Also produced when copying a policy from docs with an interval shorter than the constant ReschedulePolicyMinInterval.","commonSituations":"Copy-pasting reschedule configs from blog posts or older clusters with aggressive intervals; hand-writing Nomad job specs (HCL/JSON) with typos in duration units (e.g. \"5m\" vs \"5s\"); tools generating reschedule blocks programmatically clamping interval too low.","solutions":["Increase the reschedule policy interval to at least ReschedulePolicyMinInterval (check the constant in nomad/structs/structs.go; 15m in standard Nomad).","If you truly want unbounded retries, set unlimited: true so Interval is not validated against the minimum.","Validate the reschedule block locally before job submit with the nomad job validate command or structs.ReschedulePolicy.Validate in a unit test.","Fix duration unit typos in the HCL (e.g. meant \"1h\" not \"1m\")."],"exampleFix":"// before\nreschedule {\n  attempts = 5\n  interval  = \"10s\"\n  delay     = \"5s\"\n  delay_function = \"constant\"\n}\n// after\nreschedule {\n  attempts = 5\n  interval  = \"15m\"\n  delay     = \"5s\"\n  delay_function = \"constant\"\n}","handlingStrategy":"validation","validationCode":"const MinRescheduleInterval = 15 * time.Minute // ReschedulePolicyMinInterval\nfunc validRescheduleInterval(p *structs.ReschedulePolicy) error {\n\tif !p.Unlimited && p.Interval < MinRescheduleInterval {\n\t\treturn fmt.Errorf(\"interval %v < minimum %v\", p.Interval, MinRescheduleInterval)\n\t}\n\treturn nil\n}","typeGuard":"func hasValidInterval(p *structs.ReschedulePolicy) bool {\n\treturn p.Unlimited || p.Interval >= structs.ReschedulePolicyMinInterval\n}","tryCatchPattern":"if err := job.Validate(); err != nil {\n\tvar merr *multierror.Error\n\tif errors.As(err, &merr) {\n\t\tfor _, e := range merr.Errors {\n\t\t\tif strings.Contains(e.Error(), \"Interval cannot be less than\") {\n\t\t\t\t// fix reschedule interval before resubmit\n\t\t\t}\n\t\t}\n\t}\n}","preventionTips":["Always run `nomad job validate` before submitting jobs.","Never hand-set interval below 15m for bounded reschedule policies.","Use unlimited: true only when retries should be unbounded.","Keep duration units explicit in HCL to avoid unit typos."],"tags":["nomad","go","validation","reschedule-policy","configuration"],"backgroundTag":"reschedule-interval-below-minimum","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"}