{"record":{"id":"cfde1b211d34e45b","repo":"hashicorp/nomad","slug":"unable-to-find-eval-id-q","errorCode":null,"errorMessage":"unable to find eval id %q","messagePattern":"unable to find eval id %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store.go","lineNumber":3576,"sourceCode":"\t}\n\tif err := txn.Insert(\"index\", &IndexEntry{\"evals\", index}); err != nil {\n\t\treturn fmt.Errorf(\"index update failed: %v\", err)\n\t}\n\treturn nil\n}\n\n// updateEvalModifyIndex is used to update the modify index of an evaluation that has been\n// through a scheduler pass. This is done as part of plan apply. It ensures that when a subsequent\n// scheduler workers process a re-queued evaluation it sees any partial updates from the plan apply.\nfunc (s *StateStore) updateEvalModifyIndex(txn *txn, index uint64, evalID string) error {\n\t// Lookup the evaluation\n\texisting, err := txn.First(\"evals\", \"id\", evalID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"eval lookup failed: %v\", err)\n\t}\n\tif existing == nil {\n\t\ts.logger.Error(\"unable to find eval\", \"eval_id\", evalID)\n\t\treturn fmt.Errorf(\"unable to find eval id %q\", evalID)\n\t}\n\teval := existing.(*structs.Evaluation).Copy()\n\t// Update the indexes\n\teval.ModifyIndex = index\n\n\t// Insert the eval\n\tif err := txn.Insert(\"evals\", eval); err != nil {\n\t\treturn fmt.Errorf(\"eval insert failed: %v\", err)\n\t}\n\tif err := txn.Insert(\"index\", &IndexEntry{\"evals\", index}); err != nil {\n\t\treturn fmt.Errorf(\"index update failed: %v\", err)\n\t}\n\treturn nil\n}\n\n// DeleteEvalsByFilter is used to delete all evals that are both safe to delete\n// and match a filter.\nfunc (s *StateStore) DeleteEvalsByFilter(index uint64, filterExpr string, pageToken string, perPage int32) error {","sourceCodeStart":3558,"sourceCodeEnd":3594,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store.go#L3558-L3594","documentation":"Returned by updateEvalModifyIndex when the evaluation ID supplied by plan apply does not exist in the \"evals\" table — the txn.First lookup succeeded but returned nil. The eval ID is logged at error level along with this wrapped error. It means plan apply referenced an eval that was deleted or never inserted.","triggerScenarios":"updateEvalModifyIndex called with an evalID whose evaluation was garbage-collected (DeleteEvalsByFilter), cancelled and purged, or whose ID was mistyped/never created before plan apply ran.","commonSituations":"Stale scheduler workers applying plans after the eval was deleted; eval GC racing with plan apply; manually purged evals via API; version-mismatch between leader and followers mid-upgrade.","solutions":["Verify the eval still exists via `nomad eval status <eval-id>` / the evaluations API before plan apply","Re-run the scheduler; a fresh eval will be created and the stale apply discarded","Reduce eval GC aggressiveness (eval_gc_threshold) if evals are being reaped too early","Ensure all servers run the same Nomad version during upgrades"],"exampleFix":"// before: applying plan with stale eval id\nerr := s.updateEvalModifyIndex(txn, idx, evalID)\n// after\nexisting, _ := txn.First(\"evals\", \"id\", evalID)\nif existing != nil {\n    err = s.updateEvalModifyIndex(txn, idx, evalID)\n}","handlingStrategy":"validation","validationCode":"// Go: confirm the eval exists before plan apply\nexisting, err := txn.First(\"evals\", \"id\", evalID)\nif err != nil {\n    return err\n}\nif existing == nil {\n    return fmt.Errorf(\"eval %q no longer exists; skipping modify-index update\", evalID)\n}","typeGuard":"func evalExists(txn *txn, evalID string) bool {\n    raw, err := txn.First(\"evals\", \"id\", evalID)\n    return err == nil && raw != nil\n}","tryCatchPattern":"// Go\nif err != nil && strings.Contains(err.Error(), \"unable to find eval id\") {\n    // stale plan result; drop it and let the scheduler re-queue\n    return nil\n}","preventionTips":["Check `nomad eval status <id>` before assuming an eval exists","Tune eval_gc_threshold so GC does not reap evals mid-plan-apply","Avoid manual eval deletion while schedulers have in-flight plans","Upgrade all servers together to avoid leader/follower skew"],"tags":["nomad","eval","plan-apply","missing-entity"],"backgroundTag":"eval-not-found","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}