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

  1. Re-run 'nomad eval list' and delete only IDs currently present
  2. Handle/skip already-deleted IDs: treat 'eval not found' as success in idempotent cleanup scripts
  3. Lower the chance of GC racing cleanup by disabling job_gc/eval GC temporarily during maintenance
  4. 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

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


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