{"record":{"id":"705535ca9bee505c","repo":"hashicorp/nomad","slug":"minhealthytime-must-be-less-than-healthydeadline","errorCode":null,"errorMessage":"MinHealthyTime must be less than HealthyDeadline","messagePattern":"MinHealthyTime must be less than HealthyDeadline","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":6863,"sourceCode":"\t\t// ok\n\tcase \"\":\n\t\tif m.MaxParallel > 0 {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Missing HealthCheck\"))\n\t\t}\n\tdefault:\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"Invalid HealthCheck: %q\", m.HealthCheck))\n\t}\n\n\tif m.MinHealthyTime < 0 {\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"MinHealthyTime is %s and must be >= 0\", m.MinHealthyTime))\n\t}\n\n\tif m.HealthyDeadline < 0 {\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"HealthyDeadline is %s and must be >= 0\", m.HealthyDeadline))\n\t}\n\n\tif m.MinHealthyTime > m.HealthyDeadline {\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"MinHealthyTime must be less than HealthyDeadline\"))\n\t}\n\n\treturn mErr.ErrorOrNil()\n}\n\n// TaskGroup is an atomic unit of placement. Each task group belongs to\n// a job and may contain any number of tasks. A task group support running\n// in many replicas using the same configuration..\ntype TaskGroup struct {\n\t// Name of the task group\n\tName string\n\n\t// Count is the number of replicas of this task group that should\n\t// be scheduled.\n\tCount int\n\n\t// Update is used to control the update strategy for this task group\n\tUpdate *UpdateStrategy","sourceCodeStart":6845,"sourceCodeEnd":6881,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L6845-L6881","documentation":"MigrateStrategy.Validate enforces that MinHealthyTime is strictly less than HealthyDeadline, since an allocation must be observed healthy within the overall deadline window; if MinHealthyTime >= HealthyDeadline the criterion can never be satisfied in a meaningful way. This cross-field check runs after both individual non-negativity checks pass.","triggerScenarios":"Submitting a job where update.min_healthy_time >= update.healthy_deadline, e.g. min_healthy_time=\"10m\" with healthy_deadline=\"5m\" (or equal values).","commonSituations":"Tuning deadlines independently without noticing their relationship; template variables where the deadline was shrunk but healthy time wasn't; copy-paste between job files keeping mismatched pairs.","solutions":["Increase healthy_deadline so it exceeds min_healthy_time.","Reduce min_healthy_time below healthy_deadline.","Keep min_healthy_time well under healthy_deadline (e.g. 30s vs 5m) to leave observation headroom.","Validate with `nomad job validate` after edits."],"exampleFix":"// before\nupdate {\n  min_healthy_time = \"10m\"\n  healthy_deadline = \"5m\"\n}\n// after\nupdate {\n  min_healthy_time = \"30s\"\n  healthy_deadline = \"5m\"\n}","handlingStrategy":"validation","validationCode":"func validHealthyWindow(m *structs.MigrateStrategy) error {\n\tif m.MinHealthyTime >= m.HealthyDeadline {\n\t\treturn fmt.Errorf(\"min_healthy_time (%s) must be < healthy_deadline (%s)\", m.MinHealthyTime, m.HealthyDeadline)\n\t}\n\treturn nil\n}","typeGuard":"func hasSaneHealthyWindow(m *structs.MigrateStrategy) bool {\n\treturn m.MinHealthyTime < m.HealthyDeadline\n}","tryCatchPattern":"if err := strategy.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"MinHealthyTime must be less than HealthyDeadline\") {\n\t\t// widen healthy_deadline or shrink min_healthy_time before resubmit\n\t}\n}","preventionTips":["Keep min_healthy_time well below healthy_deadline (e.g. 30s vs 5m).","Tune the pair together, never independently, in templates.","Add a cross-field assertion wherever MigrateStrategy is constructed.","Run `nomad job validate` before every submit."],"tags":["nomad","go","validation","migrate-strategy","cross-field"],"backgroundTag":"cross-field-config-validation","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"}