{"record":{"id":"267b29a9fc233a9e","repo":"hashicorp/nomad","slug":"killtimout-s-longer-than-the-group-s-progressde","errorCode":null,"errorMessage":"KillTimout (%s) longer than the group's ProgressDeadline (%s)","messagePattern":"KillTimout \\((.+?)\\) longer than the group's ProgressDeadline \\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":8262,"sourceCode":"\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Task name cannot include null characters\"))\n\t}\n\tif t.Driver == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing task driver\"))\n\t}\n\tif t.KillTimeout < 0 {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"KillTimeout must be a positive value\"))\n\t} else {\n\t\t// Validate the group's update strategy does not conflict with the\n\t\t// task's kill_timeout for service jobs.\n\t\t//\n\t\t// progress_deadline = 0 has a special meaning so it should not be\n\t\t// validated against the task's kill_timeout.\n\t\tconflictsWithProgressDeadline := jobType == JobTypeService &&\n\t\t\ttg.Update != nil &&\n\t\t\ttg.Update.ProgressDeadline > 0 &&\n\t\t\tt.KillTimeout > tg.Update.ProgressDeadline\n\t\tif conflictsWithProgressDeadline {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"KillTimout (%s) longer than the group's ProgressDeadline (%s)\",\n\t\t\t\tt.KillTimeout, tg.Update.ProgressDeadline))\n\t\t}\n\t}\n\tif t.ShutdownDelay < 0 {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"ShutdownDelay must be a positive value\"))\n\t}\n\n\t// Validate the resources.\n\tif t.Resources == nil {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing task resources\"))\n\t} else if err := t.Resources.Validate(); err != nil {\n\t\tmErr.Errors = append(mErr.Errors, err)\n\t}\n\n\t// Validate the log config\n\tif t.LogConfig == nil {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing Log Config\"))\n\t} else if err := t.LogConfig.Validate(tg.EphemeralDisk); err != nil {","sourceCodeStart":8244,"sourceCodeEnd":8280,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L8244-L8280","documentation":"Raised during Task validation in nomad/structs/structs.go:8262 when a service job task's kill_timeout exceeds the task group's update block ProgressDeadline (and ProgressDeadline > 0). During a deployment, if a task fails health checks Nomad waits until the progress deadline before proceeding; a kill_timeout longer than that deadline makes the kill-then-restart sequence incoherent, so Nomad rejects it.","triggerScenarios":"Service job with update { progress_deadline = 5m } and a task kill_timeout = 10m; calling tg.Validate/job Validate with t.KillTimeout > tg.Update.ProgressDeadline for JobTypeService.","commonSituations":"Users raise kill_timeout so graceful shutdown can finish but forget to extend progress_deadline; defaults changed in one place (kill_timeout = 30m) interacting with a small progress_deadline; deployments stuck then failing validation after a job edit.","solutions":["Lower kill_timeout so it is <= update.progress_deadline.","Raise update { progress_deadline } to be strictly greater than kill_timeout.","Remove the custom kill_timeout to use the 5s default if graceful shutdown is not required."],"exampleFix":"// before\nupdate { progress_deadline = \"5m\" }\ntask \"web\" { kill_timeout = \"10m\" }\n// after\nupdate { progress_deadline = \"15m\" }\ntask \"web\" { kill_timeout = \"10m\" }","handlingStrategy":"validation","validationCode":"if job.Type == \"service\" && tg.Update != nil && tg.Update.ProgressDeadline > 0 {\n  for _, t := range tg.Tasks {\n    if t.KillTimeout > tg.Update.ProgressDeadline {\n      return fmt.Errorf(\"task %s: kill_timeout %s exceeds progress_deadline %s\", t.Name, t.KillTimeout, tg.Update.ProgressDeadline)\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set progress_deadline > the largest kill_timeout in the group.","Review both values together when tuning graceful shutdown.","Use nomad job validate in CI to catch cross-field conflicts."],"tags":["nomad","validation","deployment","kill-timeout"],"backgroundTag":"invalid-config-value","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"}