hashicorp/nomad · error

Only cron or crons may be used

Error message

Only cron or crons may be used

What it means

Returned by PeriodicConfig.Validate() (structs.go) when a periodic job defines BOTH the legacy single 'cron' spec (p.Spec) and the newer multi-spec 'crons' list (p.Specs). Exactly one representation of the schedule must be provided; the error is appended to a multierror.

Source

Thrown at nomad/structs/structs.go:5918

}

func (p *PeriodicConfig) Copy() *PeriodicConfig {
	if p == nil {
		return nil
	}
	np := new(PeriodicConfig)
	*np = *p
	return np
}

func (p *PeriodicConfig) Validate() error {
	if !p.Enabled {
		return nil
	}

	var mErr multierror.Error
	if p.Spec != "" && len(p.Specs) != 0 {
		_ = multierror.Append(&mErr, fmt.Errorf("Only cron or crons may be used"))
	}
	if p.Spec == "" && len(p.Specs) == 0 {
		_ = multierror.Append(&mErr, fmt.Errorf("Must specify a spec"))
	}

	// Check if we got a valid time zone
	if p.TimeZone != "" {
		if _, err := time.LoadLocation(p.TimeZone); err != nil {
			_ = multierror.Append(&mErr, fmt.Errorf("Invalid time zone %q: %v", p.TimeZone, err))
		}
	}

	switch p.SpecType {
	case PeriodicSpecCron:
		// Validate the cron spec
		if p.Spec != "" {
			if _, err := cronexpr.Parse(p.Spec); err != nil {
				_ = multierror.Append(&mErr, fmt.Errorf("Invalid cron spec %q: %v", p.Spec, err))

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Remove the legacy `cron` line and keep only `crons`, or vice versa
  2. If you need multiple schedules, use only the `crons` list
  3. Re-render your job template so only one schedule field is emitted
  4. Run `nomad job validate` before `nomad job run` to catch it early

Example fix

// before
periodic {
  cron = "*/5 * * * * *"
  crons = ["*/10 * * * * *", "0 * * * * *"]
}
// after
periodic {
  crons = ["*/10 * * * * *", "0 * * * * *"]
}
Defensive patterns

Strategy: validation

Validate before calling

if pc.Spec != "" && len(pc.Specs) != 0 {
    return fmt.Errorf("periodic block sets both cron and crons; choose one")
}

Prevention

When it happens

Trigger: Submitting a periodic job (nomad job run / /v1/jobs) whose Periodic block sets both `cron = "..."` and `crons = [...]`, or code populating both PeriodicConfig.Spec and PeriodicConfig.Specs.

Common situations: Migrating an old single-cron periodic job to the multi-cron `crons` field while leaving the old `cron` line in the HCL; templating tools that emit both fields; Nomad version drift where `crons` was added (Nomad 1.0+).

Related errors


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