{"record":{"id":"adc11dc2ca8e4242","repo":"hashicorp/nomad","slug":"s-d-job-exists-with-conflicting-job-modify-inde-adc11d","errorCode":null,"errorMessage":"%s %d: job exists with conflicting job modify index: %d","messagePattern":"(.+?) (.+?): job exists with conflicting job modify index: (.+?)","errorType":"validation","errorClass":"RegisterEnforceIndexErrPrefix","httpStatus":null,"severity":"error","filePath":"nomad/structs/job.go","lineNumber":313,"sourceCode":"\tfor _, tg := range j.TaskGroups {\n\t\tfor _, t := range tg.Tasks {\n\t\t\tif t.Schedule != nil {\n\t\t\t\tresult.Insert(tg.Name)\n\t\t\t\tbreak // to next TaskGroup\n\t\t\t}\n\t\t}\n\t}\n\treturn result\n}\n\n// EnforceIndex checks the `EnforceIndex` logic: if the job exists (not `nil`)\n// it must match the `index` argument and if `index == 0` the job must be `nil`.\nfunc (j *Job) EnforceIndex(index uint64) error {\n\tif j != nil {\n\t\tif index == 0 {\n\t\t\treturn fmt.Errorf(\"%s 0: job already exists\", RegisterEnforceIndexErrPrefix)\n\t\t} else if index != j.JobModifyIndex {\n\t\t\treturn fmt.Errorf(\"%s %d: job exists with conflicting job modify index: %d\",\n\t\t\t\tRegisterEnforceIndexErrPrefix, index, j.JobModifyIndex)\n\t\t}\n\t} else if index != 0 {\n\t\treturn fmt.Errorf(\"%s %d: job does not exist\", RegisterEnforceIndexErrPrefix, index)\n\t}\n\treturn nil\n}\n","sourceCodeStart":295,"sourceCodeEnd":321,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/job.go#L295-L321","documentation":"Job.EnforceIndex compare-and-set check: when the job exists and the requested index is non-zero but does not equal the job's JobModifyIndex, registration is rejected because the caller's view is stale. Prefixed with RegisterEnforceIndexErrPrefix.","triggerScenarios":"Job register with EnforceIndex=true and EnforceIndex set to an index value differing from the stored JobModifyIndex (e.g. after another client modified the job).","commonSituations":"Two operators editing the same job concurrently; CI re-deploying with a cached index from an earlier read; script using hardcoded index values.","solutions":["Re-read the job (GET /v1/job/...) and use the fresh JobModifyIndex","Retry the register after fetching the current index","Disable EnforceIndex if last-write-wins semantics are acceptable"],"exampleFix":"// before\nEnforceIndex: true, JobModifyIndex: 42\n// after\njob := api.Jobs().Info(...) // read current index\nEnforceIndex: true, JobModifyIndex: job.JobModifyIndex","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for i := 0; i < 3; i++ {\n  state, _, err := client.Jobs().Info(jobID)\n  if err != nil { return err }\n  job.JobModifyIndex = *state.JobModifyIndex\n  _, _, err = client.Jobs().Register(job, &api.RegisterOptions{EnforceIndex: true})\n  if err == nil || !strings.Contains(err.Error(), \"conflicting job modify index\") { return err }\n}","preventionTips":["Always read JobModifyIndex immediately before register","Refresh the index on every CAS conflict instead of reusing cached values","Avoid concurrent writers to the same job ID"],"tags":["nomad","job-register","enforce-index","cas","conflict"],"backgroundTag":"enforce-index-mismatch","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"}