hashicorp/nomad · warning

evaluation not blocked

Error message

evaluation not blocked

What it means

This error is returned by the Evaluations.Reblock RPC when the evaluation being reblocked exists but its status is not 'blocked'. Reblocking is only valid for evals already in the blocked state; anything else (pending, complete, failed, cancelled) is rejected.

Source

Thrown at nomad/eval_endpoint.go:409

		return err
	}

	// Look for the eval
	snap, err := e.srv.fsm.State().Snapshot()
	if err != nil {
		return err
	}

	ws := memdb.NewWatchSet()
	out, err := snap.EvalByID(ws, eval.ID)
	if err != nil {
		return err
	}
	if out == nil {
		return fmt.Errorf("evaluation does not exist")
	}
	if out.Status != structs.EvalStatusBlocked {
		return fmt.Errorf("evaluation not blocked")
	}

	// Reblock the eval
	e.srv.blockedEvals.Reblock(eval, args.EvalToken)
	return nil
}

// Reap is used to cleanup dead evaluations and allocations
func (e *Eval) Reap(args *structs.EvalReapRequest,
	reply *structs.GenericResponse) error {

	aclObj, err := e.srv.AuthenticateServerOnly(e.ctx, args)
	e.srv.MeasureRPCRate("eval", structs.RateMetricWrite, args)
	if err != nil || !aclObj.AllowServerOp() {
		return structs.ErrPermissionDenied
	}

	if done, err := e.srv.forward("Eval.Reap", args, args, reply); done {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Fetch the eval first and confirm its Status is 'blocked' before calling Reblock
  2. Treat the error as benign/no-op if the eval already completed — no reblock is needed
  3. Refresh the eval ID from the scheduler rather than reusing a cached one

Example fix

// before
e.srv.blockedEvals.Reblock(eval, args.EvalToken)
// after
if eval.Status == structs.EvalStatusBlocked {
    e.srv.blockedEvals.Reblock(eval, args.EvalToken)
}
Defensive patterns

Strategy: validation

Validate before calling

eval, _, err := client.Evaluations().Get(evalID)
if err != nil { return err }
if eval.Status != "blocked" { return fmt.Errorf("eval %s is %s, not blocked", evalID, eval.Status) }

Type guard

func isBlocked(e *api.Evaluation) bool { return e != nil && e.Status == "blocked" }

Prevention

When it happens

Trigger: Calling the Reblock RPC (or an API path that invokes it) with an eval ID whose current status is not structs.EvalStatusBlocked, e.g. the eval already completed or was cancelled between when the client saw it and when Reblock ran.

Common situations: Retry logic re-submitting a reblock after the eval was already reblocked or finalized; a deployment/alloc watcher acting on a stale eval ID; race conditions where the scheduler unblocked or finalized the eval concurrently.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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