hashicorp/nomad · error
StopAfterClientDisconnect is deprecated and ignored favor of
Error message
StopAfterClientDisconnect is deprecated and ignored favor of Disconnect.StopOnClientAfter
What it means
TaskGroup.Validate rejects the deprecated task-group field StopAfterClientDisconnect. Nomad replaced the ad-hoc client-disconnect handling fields with the structured `disconnect` block; setting the old field makes the job specification invalid. The error is accumulated into the group's multierror during job validation.
Source
Thrown at nomad/structs/structs.go:7657
func (tg *TaskGroup) Warnings(j *Job) error {
var mErr multierror.Error
// Validate the update strategy
if u := tg.Update; u != nil {
// Check the counts are appropriate
if tg.Count > 1 && u.MaxParallel > tg.Count && !(j.IsMultiregion() && tg.Count == 0) {
mErr.Errors = append(mErr.Errors,
fmt.Errorf("Update max parallel count is greater than task group count (%d > %d). "+
"A destructive change would result in the simultaneous replacement of all allocations.", u.MaxParallel, tg.Count))
}
}
if tg.MaxClientDisconnect != nil {
mErr.Errors = append(mErr.Errors, errors.New("MaxClientDisconnect is deprecated and ignored in favor of Disconnect.LostAfter"))
}
if tg.StopAfterClientDisconnect != nil {
mErr.Errors = append(mErr.Errors, errors.New("StopAfterClientDisconnect is deprecated and ignored favor of Disconnect.StopOnClientAfter"))
}
if tg.PreventRescheduleOnLost {
mErr.Errors = append(mErr.Errors, errors.New("PreventRescheduleOnLost is deprecated and ignored in favor of Disconnect.Replace"))
}
// Warn about unbounded rescheduling which may cause thrashing if tasks have
// unlimited attempts and a low delay.
//
// The 5 second gate on the delay is used as this was the previous minimum
// value which did not produce a warning. It therefore feels like the right
// gate to use.
if rp := tg.ReschedulePolicy; rp != nil && rp.Unlimited && rp.Delay < 5*time.Second {
mErr.Errors = append(
mErr.Errors,
errors.New("Reschedule policy has unlimited attempts enabled and a low delay; reschedule thrashing possible"),
)
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Remove stop_after_client_disconnect from the task group.
- Add a `disconnect { stop_on_client_after = <duration> }` block with the equivalent value.
- Re-run `nomad job validate` (or the API validate endpoint) to confirm no other deprecated fields remain.
Example fix
// before
group "web" {
stop_after_client_disconnect = "15m"
}
// after
group "web" {
disconnect {
stop_on_client_after = "15m"
}
} Defensive patterns
Strategy: validation
Validate before calling
for _, dep := range []string{"stop_after_client_disconnect"} {
if strings.Contains(jobHCL, dep) {
return fmt.Errorf("group uses deprecated %s; migrate to disconnect { stop_on_client_after }", dep)
}
} Type guard
func usesLegacyDisconnect(tg *structs.TaskGroup) bool {
return tg.StopAfterClientDisconnect != nil
} Prevention
- Run `nomad job validate` in CI on every job file.
- Grep job repos for deprecated fields after each Nomad upgrade.
- Prefer the disconnect block in all new job specs.
- Pin a lint rule banning stop_after_client_disconnect.
When it happens
Trigger: Submitting or validating a job whose group still sets `stop_after_client_disconnect` (or StopAfterClientDisconnect in Go) after upgrading to a Nomad version that deprecates it in favor of `disconnect { stop_on_client_after = ... }`.
Common situations: Upgrading an older Nomad job file (pre-1.7/1.8 style) that used stop_after_client_disconnect for lost-client behavior; copy-pasting legacy HCL/JSON jobs into a newer cluster.
Related errors
- PreventRescheduleOnLost is deprecated and ignored in favor o
- Disconnect cannot be configured with both lost_after and sto
- lost_after cannot be a negative duration
- stop_after cannot be a negative duration
- Missing job ID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/a964ef71fb62ea12.
Report an issue: GitHub.