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

  1. Verify the targeted Nomad server is the current leader (use nomad monitor or query /v1/status/leader).
  2. Retry the force-run against the leader or via the HTTP API, which forwards to the leader.
  3. Wait for leader election to complete before forcing evaluations.
  4. 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

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


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