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
- Remove the legacy `cron` line and keep only `crons`, or vice versa
- If you need multiple schedules, use only the `crons` list
- Re-render your job template so only one schedule field is emitted
- 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 migrating to `crons`, delete the old `cron` line
- Use `nomad job validate` before every `nomad job run`
- Ensure templates emit exactly one schedule field
- Add CI linting for periodic job HCL
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
- Must specify a spec
- missing secret ID
- namespace cannot contain template delimiters or parenthesis
- wait config is nil or empty
- CSI.ControllerAttachVolume: VolumeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/21bb8dbd20ba6c56.
Report an issue: GitHub.