{"record":{"id":"843eedbb556444c0","repo":"hashicorp/nomad","slug":"interval-can-not-be-less-than-v-got-v","errorCode":null,"errorMessage":"Interval can not be less than %v (got %v)","messagePattern":"Interval can not be less than (.+?) \\(got (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":6579,"sourceCode":"\t*nrp = *r\n\treturn nrp\n}\n\nfunc (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","sourceCodeStart":6561,"sourceCodeEnd":6597,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L6561-L6597","documentation":"RestartPolicy.Validate() enforces a minimum interval (RestartPolicyMinInterval, 1 minute by default). An interval smaller than this floor is rejected because restart throttling below that granularity is not supported.","triggerScenarios":"A restart block with interval set below the minimum (e.g. interval = \"30s\"), or interval parsed as plain seconds/zero due to a unit mistake in HCL or JSON job submission.","commonSituations":"Unit confusion (\"30\" meaning 30s instead of 30m), copy-pasting durations from configs using different units, or generating policies in code with time.Duration in the wrong magnitude.","solutions":["Raise restart_policy.interval to at least the minimum (>= 1m; default is 30m).","Verify duration units in HCL (e.g. \"30m\", not 30).","Run `nomad job validate` to see the exact minimum printed in the error."],"exampleFix":"// before\nrestart {\n  interval = \"30s\"\n  attempts = 2\n  delay    = \"15s\"\n}\n// after\nrestart {\n  interval = \"30m\"\n  attempts = 2\n  delay    = \"15s\"\n}","handlingStrategy":"validation","validationCode":"if rp != nil && rp.Interval.Nanoseconds() < structs.RestartPolicyMinInterval.Nanoseconds() {\n    return fmt.Errorf(\"restart interval %v < minimum %v\", rp.Interval, structs.RestartPolicyMinInterval)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write durations with explicit units (\"30m\", not 30).","Compare against structs.RestartPolicyMinInterval when generating policies.","Keep defaults (interval 30m) unless you have a specific reason."],"tags":["nomad","validation","duration","restart-policy"],"backgroundTag":"value-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"}