{"record":{"id":"bb4f5921d94f770e","repo":"hashicorp/nomad","slug":"evaluation-id-not-found","errorCode":null,"errorMessage":"Evaluation ID not found","messagePattern":"Evaluation ID not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/eval_broker.go","lineNumber":610,"sourceCode":"\tif !unack.NackTimer.Reset(b.nackTimeout) {\n\t\treturn ErrNackTimeoutReached\n\t}\n\treturn nil\n}\n\n// Ack is used to positively acknowledge handling an evaluation\nfunc (b *EvalBroker) Ack(evalID, token string) error {\n\tb.l.Lock()\n\tdefer b.l.Unlock()\n\n\t// Always delete the requeued evaluation. Either the Ack is successful and\n\t// we requeue it or it isn't and we want to remove it.\n\tdefer delete(b.requeue, token)\n\n\t// Lookup the unack'd eval\n\tunack, ok := b.unack[evalID]\n\tif !ok {\n\t\treturn fmt.Errorf(\"Evaluation ID not found\")\n\t}\n\tif unack.Token != token {\n\t\treturn fmt.Errorf(\"Token does not match for Evaluation ID\")\n\t}\n\tjobID := unack.Eval.JobID\n\n\tdefer b.handleAckNackLocked(unack.Eval)\n\n\t// Ensure we were able to stop the timer\n\tif !unack.NackTimer.Stop() {\n\t\treturn fmt.Errorf(\"Evaluation ID Ack'd after Nack timer expiration\")\n\t}\n\n\t// Update the stats\n\tb.stats.TotalUnacked -= 1\n\tqueue := unack.Eval.Type\n\tif b.evals[evalID] > b.deliveryLimit {\n\t\tqueue = failedQueue","sourceCodeStart":592,"sourceCodeEnd":628,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/eval_broker.go#L592-L628","documentation":"Ack is called by a scheduler worker to acknowledge a dequeued evaluation; this error means no evaluation with the given ID is currently in the unacked (in-flight) map b.unack. Either the eval was already acked/nacked, its nack timer expired and it was requeued, or the ID is simply wrong. Ack is idempotent-hostile by design: each dequeue must be acked exactly once.","triggerScenarios":"Calling Ack(evalID, token) with an evalID that was never dequeued by this broker, calling it twice for the same dequeue, or calling it after the nack timer already fired and removed the unack entry.","commonSituations":"Slow worker acks after the nack timeout elapsed so the eval was requeued to another worker; duplicate Ack from a retried handler; a bug where evalID/token get swapped or truncated; long-blocking handler exceeding nackTimeout.","solutions":["Ensure each Dequeue result is acked exactly once, within the nack timeout.","Check that the caller stored the correct evalID/token pair returned from Dequeue.","Increase the nack timeout if handlers legitimately take longer than the current timeout.","Treat this error as benign in retry logic — the eval was requeued and will be redelivered; just drop the stale ack.","Verify the handler isn't acking after a Nack for the same eval."],"exampleFix":"// before\nfunc handle(ev *structs.Evaluation, tok string) {\n\tprocess(ev) // may exceed nack timeout\n\tbroker.Ack(ev.ID, tok) // may hit \"not found\"\n}\n// after\ndone := make(chan struct{})\ngo func() { process(ev); close(done) }()\nselect {\ncase <-done:\n\tbroker.Ack(ev.ID, tok)\ncase <-time.After(nackTimeout/2):\n\tbroker.Nack(ev.ID, tok) // explicitly give up before timer fires\n}","handlingStrategy":"try-catch","validationCode":"// track in-flight (evalID -> token) pairs per worker\ninflight := map[string]string{}\nfunc canAck(evalID, token string) bool {\n\tt, ok := inflight[evalID]\n\treturn ok && t == token\n}","typeGuard":null,"tryCatchPattern":"if err := broker.Ack(evalID, token); err != nil {\n\tif strings.Contains(err.Error(), \"Evaluation ID not found\") {\n\t\t// already acked/nacked or timer fired; eval was requeued\n\t\tlog.Printf(\"stale ack for eval %s\", evalID)\n\t\treturn nil\n\t}\n\treturn err\n}","preventionTips":["Ack within the nack timeout, never after","Ack exactly once per dequeue","Store the Dequeue (evalID, token) pair together","Keep handler latency well below the nack timeout"],"tags":["go","nomad","scheduler","broker","concurrency"],"backgroundTag":"ack-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"}