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
- Fetch the eval first and confirm its Status is 'blocked' before calling Reblock
- Treat the error as benign/no-op if the eval already completed — no reblock is needed
- 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
- Always GET the eval and check Status == "blocked" before reblocking
- Treat reblock failures on terminal evals as no-ops in retry loops
- Avoid caching eval IDs across scheduling ticks
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
- eval %s is not safe to delete
- force launch for job %q failed: %v
- no servers
- missing NodeID
- missing AllocID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/a796695598c624f6.
Report an issue: GitHub.