{"record":{"id":"c429daeb13172c9d","repo":"hashicorp/nomad","slug":"job-not-found-c429da","errorCode":null,"errorMessage":"job not found","messagePattern":"job not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store.go","lineNumber":1969,"sourceCode":"\tdefer txn.Abort()\n\n\terr := s.DeleteJobTxn(index, namespace, jobID, txn)\n\tif err == nil {\n\t\treturn txn.Commit()\n\t}\n\treturn err\n}\n\n// DeleteJobTxn is used to deregister a job, like DeleteJob,\n// but in a transaction.  Useful for when making multiple modifications atomically\nfunc (s *StateStore) DeleteJobTxn(index uint64, namespace, jobID string, txn Txn) error {\n\t// Lookup the node\n\texisting, err := txn.First(\"jobs\", \"id\", namespace, jobID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"job lookup failed: %v\", err)\n\t}\n\tif existing == nil {\n\t\treturn fmt.Errorf(\"job not found\")\n\t}\n\n\t// Check if we should update a parent job summary\n\tjob := existing.(*structs.Job)\n\tif job.ParentID != \"\" {\n\t\tsummaryRaw, err := txn.First(\"job_summary\", \"id\", namespace, job.ParentID)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to retrieve summary for parent job: %v\", err)\n\t\t}\n\n\t\t// Only continue if the summary exists. It could not exist if the parent\n\t\t// job was removed\n\t\tif summaryRaw != nil {\n\t\t\texisting := summaryRaw.(*structs.JobSummary)\n\t\t\tpSummary := existing.Copy()\n\t\t\tif pSummary.Children != nil {\n\n\t\t\t\tmodified := false","sourceCodeStart":1951,"sourceCodeEnd":1987,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store.go#L1951-L1987","documentation":"StateStore.DeleteJobTxn (nomad/state/state_store.go:1969) returns this when the jobs table has no row for (namespace, jobID) at delete time. Deregistering a job that the state store cannot find is treated as an application-level error and the transaction aborts with 'job not found'.","triggerScenarios":"Job.Deregister RPC for a jobID/namespace combination that was never registered, or that was already deleted (double deregister, GC already purged it).","commonSituations":"Typo in job ID or wrong -namespace; two concurrent deregisters racing so the second finds nothing; job already removed by garbage collection after being stopped; deregistering against the wrong region/cluster.","solutions":["Verify the job ID and namespace exist first (nomad job status <id> / GET /v1/job/<id> in that namespace)","Treat 'job not found' as idempotent success if the goal is best-effort deregistration","Check whether GC or another process already deleted the job before re-submitting","Confirm you are pointed at the correct region/cluster"],"exampleFix":"// before\nerr := s.DeleteJobTxn(idx, ns, jobID, txn)\nreturn err\n// after\nif err := s.DeleteJobTxn(idx, ns, jobID, txn); err != nil {\n    if err.Error() == \"job not found\" {\n        return nil // idempotent delete\n    }\n    return err\n}","handlingStrategy":"validation","validationCode":"// confirm the job exists before deregistering\nstatus, _, err := client.Jobs().Info(jobID, &api.QueryOptions{Namespace: ns})\nif err != nil || status == nil {\n    return nil // job absent; skip delete instead of triggering 'job not found'\n}","typeGuard":"func jobPresent(raw interface{}) bool { return raw != nil } // mirrors txn.First nil check","tryCatchPattern":"if err := s.DeleteJobTxn(idx, ns, jobID, txn); err != nil {\n    if err.Error() == \"job not found\" {\n        return nil // treat as idempotent success\n    }\n    return err\n}","preventionTips":["Always check job ID and namespace spelling before deregistering","Make deregistration idempotent — a second delete racing the first gets 'job not found'","Remember GC may already have purged stopped jobs","Target the correct region/cluster and namespace"],"tags":["state-store","job","deregistration"],"backgroundTag":"job-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"}