hashicorp/nomad · error
periodic dispatch disabled
Error message
periodic dispatch disabled
What it means
PeriodicDispatch.ForceEval returns this when the periodic dispatcher is not enabled (the server is not the leader or periodic dispatch has been stopped). Force-run requests cannot be processed while disabled.
Source
Thrown at nomad/periodic.go:289
// Signal an update.
select {
case p.updateCh <- struct{}{}:
default:
}
p.logger.Debug("deregistered periodic job", "job", job.NamespacedID())
return nil
}
// ForceEval causes the periodic job to be evaluated immediately and returns the
// subsequent eval.
func (p *PeriodicDispatch) ForceEval(namespace, jobID string) (*structs.Evaluation, error) {
p.l.Lock()
// Do nothing if not enabled
if !p.enabled {
p.l.Unlock()
return nil, fmt.Errorf("periodic dispatch disabled")
}
tuple := structs.NamespacedID{
ID: jobID,
Namespace: namespace,
}
job, tracked := p.tracked[tuple]
if !tracked {
p.l.Unlock()
return nil, fmt.Errorf("can't force run non-tracked job %q (%s)", jobID, namespace)
}
p.l.Unlock()
return p.createEval(job, time.Now().In(job.Periodic.GetLocation()))
}
// shouldRun returns whether the long lived run function should run.
func (p *PeriodicDispatch) shouldRun() bool {View on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the targeted Nomad server is the current leader (use nomad monitor or query /v1/status/leader).
- Retry the force-run against the leader or via the HTTP API, which forwards to the leader.
- Wait for leader election to complete before forcing evaluations.
- If persistent, check server logs for leadership flapping.
Example fix
// before
eval, _ := dispatcher.ForceEval(ns, jobID)
// after
eval, err := dispatcher.ForceEval(ns, jobID)
if err != nil && strings.Contains(err.Error(), "periodic dispatch disabled") {
return retryAgainstLeader(ns, jobID)
} Defensive patterns
Strategy: retry
Validate before calling
// Go: check leadership before ForceEval leader := statusAPI.Leader() // only proceed if this server reports itself as leader
Try / catch
// Go
eval, err := d.ForceEval(ns, jobID)
if err != nil && err.Error() == "periodic dispatch disabled" {
time.Sleep(backoff)
return d.ForceEval(ns, jobID) // retry or redirect to leader
} Prevention
- Always route force-run requests through the leader-forwarding HTTP API
- Wait for stable leadership before issuing force commands
- Add retry with backoff around ForceEval
When it happens
Trigger: Calling ForceEval when p.enabled is false — typically on a non-leader server, before the dispatcher starts, or after it was stopped during leadership loss/shutdown.
Common situations: Forcing a periodic job run right after a leader election where this server is no longer leader; calling ForceEval during server shutdown; restorePeriodicDispatcher racing with disable.
Related errors
- leadership transfer not supported with Raft version lower th
- failed to transfer leadership in %d attempts. last error: %w
- failed to add job %v: %v
- failed to remove tracked job %q (%s): %v
- can't force run non-tracked job %q (%s)
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/93e8145d794e62d9.
Report an issue: GitHub.