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.
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
- Deployment ID couldn't be updated as it does not exist
- job not found
- job version not found
- launch not found
- node pool not found
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/17412e70a0cd17b5.
Report an issue: GitHub.
Appendix: 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)