hashicorp/nomad · error

must specify cron block

Error message

must specify cron block

What it means

TaskSchedule.Validate requires a cron block: a TaskSchedule with a nil Cron field is structurally invalid, so validation stops immediately with "must specify cron block". The schedule is defined entirely by its TaskScheduleCron expression, so without it there is nothing to evaluate.

Source

Thrown at nomad/structs/task_sched.go:67

	TaskScheduleStateRun        TaskScheduleState = ""
	TaskScheduleStateForceRun   TaskScheduleState = "force_run"
	TaskScheduleStateSchedPause TaskScheduleState = "scheduled_pause"
	TaskScheduleStateForcePause TaskScheduleState = "force_pause"
	// TaskScheduleStateSchedResume is a transitory state that will become
	// either SchedPause or (sched) Run
	TaskScheduleStateSchedResume TaskScheduleState = "schedule_resume"
)

// TaskSchedule allows specifying a time based execution schedule for tasks.
//
// Enterprise only.
type TaskSchedule struct {
	Cron *TaskScheduleCron
}

func (t *TaskSchedule) Validate() error {
	if t.Cron == nil {
		return errors.New("must specify cron block")
	}

	const (
		startFields     = 6
		endFields       = 2
		restrictedChars = "/,"
	)

	if strings.Count(t.Cron.Start, " ") != (startFields - 1) {
		return fmt.Errorf("cron.start must contain %d fields", startFields)
	}
	if strings.Count(t.Cron.End, " ") != (endFields - 1) {
		return fmt.Errorf("cron.end must contain %d fields", endFields)
	}
	if strings.ContainsAny(t.Cron.Start, restrictedChars) {
		return fmt.Errorf("cron.start must not contain %q", restrictedChars)
	}
	if strings.ContainsAny(t.Cron.End, restrictedChars) {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add a cron block with a valid cron expression inside the schedule stanza.
  2. If no schedule is intended, omit the whole schedule block rather than emitting an empty one.
  3. Fix HCL block naming so the cron section parses into t.Cron instead of being ignored.

Example fix

// before (HCL)
schedule {
}
// after
schedule {
  cron = "0 2 * * *"
}
Defensive patterns

Strategy: validation

Validate before calling

func validSchedule(t *structs.TaskSchedule) bool {
	return t != nil && t.Cron != nil
}
if !validSchedule(sched) {
	return errors.New("schedule requires a cron block")
}

Type guard

func hasCron(t *structs.TaskSchedule) bool { return t != nil && t.Cron != nil }

Try / catch

if err := sched.Validate(); err != nil && strings.Contains(err.Error(), "must specify cron") {
	// fix the config: add a cron block before resubmitting
}

Prevention

When it happens

Trigger: Constructing or submitting a task schedule (e.g. in a Nomad task scheduler/variable-related schedule stanza) with the schedule block present but no cron child block; programmatically creating structs.TaskSchedule{} without setting Cron.

Common situations: Hand-written HCL where the cron stanza was omitted or misnamed; tests and tooling building TaskSchedule literals; partial config merges that dropped the cron section.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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