hashicorp/nomad · error

System or sysbatch jobs should not have a reschedule policy

Error message

System or sysbatch jobs should not have a reschedule policy

What it means

Nomad validation rejects a reschedule policy on System or SysBatch jobs. These job types run one allocation per eligible node and are not re-placed by the scheduler after failures, so a `reschedule` stanza has no effect and is considered a configuration error. Detected when `j.Type` is `JobTypeSystem` or `JobTypeSysBatch` and `tg.ReschedulePolicy != nil`.

Source

Thrown at nomad/structs/structs.go:7202

		mErr = multierror.Append(mErr, fmt.Errorf("Task Group %v should have a restart policy", tg.Name))
	}

	if j.Type == JobTypeSystem {
		if tg.Spreads != nil {
			mErr = multierror.Append(mErr, fmt.Errorf("System jobs may not have a spread block"))
		}
	} else {
		for idx, spread := range tg.Spreads {
			if err := spread.Validate(); err != nil {
				outer := fmt.Errorf("Spread %d validation failed: %s", idx+1, err)
				mErr = multierror.Append(mErr, outer)
			}
		}
	}

	if j.Type == JobTypeSystem || j.Type == JobTypeSysBatch {
		if tg.ReschedulePolicy != nil {
			mErr = multierror.Append(mErr, fmt.Errorf("System or sysbatch jobs should not have a reschedule policy"))
		}
	} else {
		if tg.ReschedulePolicy != nil {
			if err := tg.ReschedulePolicy.Validate(); err != nil {
				mErr = multierror.Append(mErr, err)
			}
		} else {
			mErr = multierror.Append(mErr, fmt.Errorf("Task Group %v should have a reschedule policy", tg.Name))
		}
	}

	if tg.EphemeralDisk != nil {
		if err := tg.EphemeralDisk.Validate(); err != nil {
			mErr = multierror.Append(mErr, err)
		}
	} else {
		mErr = multierror.Append(mErr, fmt.Errorf("Task Group %v should have an ephemeral disk object", tg.Name))
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Remove the `reschedule` block from each task group in the system/sysbatch job.
  2. If rescheduling on failure is required, use a `service` (or `batch`) job type instead.
  3. Validate the job spec with `nomad job validate` before submission.

Example fix

// before
job "backup" {
  type = "sysbatch"
  group "backup" {
    reschedule {
      attempts = 3
      interval = "10m"
    }
  }
}
// after
job "backup" {
  type = "sysbatch"
  group "backup" {
  }
}
Defensive patterns

Strategy: validation

Validate before calling

func validateNoRescheduleOnSystem(j *api.Job) error {
	if j == nil {
		return nil
	}
	if *j.Type == "system" || *j.Type == "sysbatch" {
		for _, tg := range j.TaskGroups {
			if tg.ReschedulePolicy != nil && *tg.ReschedulePolicy != (api.ReschedulePolicy{}) {
				return fmt.Errorf("group %s: system/sysbatch jobs should not have a reschedule policy", *tg.Name)
			}
		}
	}
	return nil
}

Type guard

func isSystemFamily(j *api.Job) bool { return j != nil && (*j.Type == "system" || *j.Type == "sysbatch") }

Prevention

When it happens

Trigger: Submitting a job with `type = "system"` or `type = "sysbatch"` whose task group defines a `reschedule { ... }` stanza, or where reschedule policy is set programmatically on the group.

Common situations: Converting a service job to system/sysbatch without stripping the reschedule block; shared base group templates that include reschedule for all job types; older job files carried forward across job-type changes.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/fff5b87a7771ee3f. Report an issue: GitHub.