hashicorp/nomad · error
eval not found
Error message
eval not found
What it means
During Eval.Delete, each requested eval ID is looked up in a state-store snapshot via EvalByID. If the ID does not exist in the state store, the delete transaction aborts with this error rather than silently skipping the unknown eval.
Source
Thrown at nomad/eval_endpoint.go:519
if err != nil {
return fmt.Errorf("failed to lookup state snapshot: %v", err)
}
ws := memdb.NewWatchSet()
count := 0
// Iterate the evaluations and ensure they are safe to delete. It is
// possible passed evals are not safe to delete and would make Nomads state
// a little wonky. The nature of the RPC return error, means a single
// unsafe eval ID fails the whole call.
for _, evalID := range args.EvalIDs {
evalInfo, err := serverStateSnapshot.EvalByID(ws, evalID)
if err != nil {
return fmt.Errorf("failed to lookup eval: %v", err)
}
if evalInfo == nil {
return errors.New("eval not found")
}
ok, err := serverStateSnapshot.EvalIsUserDeleteSafe(ws, evalInfo)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("eval %s is not safe to delete", evalInfo.ID)
}
count++
}
// Generate the Raft request object using the reap request object. This
// avoids adding new Raft messages types and follows the existing reap
// flow.
raftReq := structs.EvalReapRequest{
Evals: args.EvalIDs,
UserInitiated: true,
WriteRequest: args.WriteRequest,View on GitHub (pinned to 482b49bf1a)
Solutions
- Re-run 'nomad eval list' and delete only IDs currently present
- Handle/skip already-deleted IDs: treat 'eval not found' as success in idempotent cleanup scripts
- Lower the chance of GC racing cleanup by disabling job_gc/eval GC temporarily during maintenance
- Verify the eval ID (UUID) is correct — no typos or truncated IDs
Example fix
// before (non-idempotent) for id in $(cat old_evals); do nomad eval delete $id; done // after (skip GC'd evals) for id in $(nomad eval list -json | jq -r '.[].ID'); do nomad eval delete "$id" || true done
Defensive patterns
Strategy: validation
Validate before calling
// shell: verify the eval still exists before deleting
nomad eval list -json | jq -e --arg id "$ID" 'map(.ID) | index($id)' >/dev/null \
|| { echo "eval $ID already gone"; exit 0; } Try / catch
// shell: idempotent delete nomad eval delete "$ID" 2>/dev/null \ || echo "eval $ID not found — treating as already deleted"
Prevention
- Refresh eval lists immediately before deletion (avoid stale caches)
- Write cleanup scripts idempotently so 'not found' is a success
- Be aware of job/eval GC racing your maintenance scripts
- Validate UUIDs to catch typos/truncation
When it happens
Trigger: Deleting an eval by an ID that has already been garbage-collected, purged, or was typo'd; racing job deregistration which removed the eval between listing and deleting.
Common situations: Scripting eval cleanup from a cached list while Nomad GC has already removed old evals; re-running a cleanup script twice; deleting evals after restoring state or pruning with job GC.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- variable doesn't exist
- unknown deployment %q
- job %q not found
- launch not found
- Deployment ID %q couldn't be updated as it does not exist
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/17412e70a0cd17b5.
Report an issue: GitHub.