hashicorp/nomad · error
can't evaluate periodic job
Error message
can't evaluate periodic job
What it means
The Job.Evaluate RPC refuses to force an evaluation on a periodic job. Periodic jobs generate child dispatch jobs on their schedule; forcing an evaluation on the parent has no defined meaning, so Nomad rejects it explicitly via job.IsPeriodic().
Source
Thrown at nomad/job_endpoint.go:718
return fmt.Errorf("missing job ID for evaluation")
}
// Lookup the job
snap, err := j.srv.fsm.State().Snapshot()
if err != nil {
return err
}
ws := memdb.NewWatchSet()
job, err := snap.JobByID(ws, args.RequestNamespace(), args.JobID)
if err != nil {
return err
}
if job == nil {
return fmt.Errorf("job not found")
}
if job.IsPeriodic() {
return fmt.Errorf("can't evaluate periodic job")
} else if job.IsParameterized() {
return fmt.Errorf("can't evaluate parameterized job")
}
forceRescheduleAllocs := make(map[string]*structs.DesiredTransition)
if args.EvalOptions.ForceReschedule {
// Find any failed allocs that could be force rescheduled
allocs, err := snap.AllocsByJob(ws, args.RequestNamespace(), args.JobID, false)
if err != nil {
return err
}
for _, alloc := range allocs {
taskGroup := job.LookupTaskGroup(alloc.TaskGroup)
// Forcing rescheduling is only allowed if task group has rescheduling enabled
if taskGroup == nil || !taskGroup.ReschedulePolicy.Enabled() {
continueView on GitHub (pinned to 482b49bf1a)
Solutions
- Evaluate the periodic child job (e.g. <parent>/<timestamp>) instead of the parent
- Use the periodic force endpoint POST /v1/job/<id>/periodic/force to trigger a run now
- Filter periodic jobs out of bulk-evaluation automation (check job.Periodic != nil client-side)
- Adjust the schedule in the job spec if a run is needed at a different time
Example fix
// before
for _, j := range jobs { client.Jobs().Evaluate(j.ID, nil) }
// after
for _, j := range jobs {
if j.Periodic != nil { continue }
client.Jobs().Evaluate(j.ID, nil)
} Defensive patterns
Strategy: validation
Validate before calling
job, _, err := client.Jobs().Info(jobID, nil)
if err != nil { return err }
if job.Periodic != nil {
return fmt.Errorf("%s is periodic; dispatch/force a child instead", jobID)
} Type guard
func isPeriodicParent(j *api.Job) bool { return j != nil && j.Periodic != nil } Try / catch
if _, _, err := client.Jobs().Evaluate(jobID, nil); err != nil && strings.Contains(err.Error(), "can't evaluate periodic") {
_, _, err = client.Jobs().ForcePeriodic(jobID, nil)
} Prevention
- Skip jobs with Periodic set in bulk evaluation loops
- Use POST /v1/job/<id>/periodic/force to trigger periodic runs
- Evaluate spawned child jobs, never the parent template
When it happens
Trigger: POST /v1/job/<id>/evaluate with the ID of a job whose Periodic block is set (a periodic parent job), e.g. running 'nomad job eval' or calling Evaluate on the parent instead of a spawned child run.
Common situations: Automation iterating over all jobs and calling Evaluate on each, hitting periodic parents; operators trying to 're-run' a periodic job by evaluating it instead of using force/periodic force endpoints.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- unimplemented for this plugin
- failed adding job to periodic dispatcher: %v
- periodicDispatcher.Remove failed: %w
- can't evaluate parameterized job
- periodic launch lookup failed: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/8064483f4d321d06.
Report an issue: GitHub.