{"record":{"id":"c89d0cde85866c0a","repo":"hashicorp/nomad","slug":"unable-to-update-job-scaling-policies-v","errorCode":null,"errorMessage":"unable to update job scaling policies: %v","messagePattern":"unable to update job scaling policies: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/state/state_store.go","lineNumber":1892,"sourceCode":"\t\tupdated, err := txn.First(\"jobs\", \"id\", job.Namespace, job.ID)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"job lookup failed: %v\", err)\n\t\t}\n\t\tif updated != nil {\n\t\t\tjob = updated.(*structs.Job)\n\t\t}\n\t}\n\n\tif err := s.updateSummaryWithJob(index, job, txn); err != nil {\n\t\treturn fmt.Errorf(\"unable to create job summary: %v\", err)\n\t}\n\n\tif err := s.upsertJobVersion(index, job, txn); err != nil {\n\t\treturn fmt.Errorf(\"unable to upsert job into job_version table: %v\", err)\n\t}\n\n\tif err := s.updateJobScalingPolicies(index, job, txn); err != nil {\n\t\treturn fmt.Errorf(\"unable to update job scaling policies: %v\", err)\n\t}\n\n\tif err := s.updateJobRecommendations(index, txn, existingJob, job); err != nil {\n\t\treturn fmt.Errorf(\"unable to update job recommendations: %v\", err)\n\t}\n\n\tif err := s.updateJobCSIPlugins(index, job, existingJob, txn); err != nil {\n\t\treturn fmt.Errorf(\"unable to update job csi plugins: %v\", err)\n\t}\n\n\tif err := s.updateJobSubmission(index, sub, job.Namespace, job.ID, job.Version, txn); err != nil {\n\t\treturn fmt.Errorf(\"unable to update job submission: %v\", err)\n\t}\n\n\tif err := s.updatePreservedValues(job, existingJob, req); err != nil {\n\t\treturn fmt.Errorf(\"unable to update preserved values: %v\", err)\n\t}\n","sourceCodeStart":1874,"sourceCodeEnd":1910,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/state/state_store.go#L1874-L1910","documentation":"UpsertJob failed while syncing the job's scaling policies via updateJobScalingPolicies, which upserts/deletes entries in the scaling policy table to match the newly submitted job spec. The wrapped error aborts the whole registration transaction.","triggerScenarios":"Submitting a job that contains scaling policy blocks (or removing them) where the scaling-policy table write fails within the transaction.","commonSituations":"Jobs using the scaling stanza during cluster upgrades or with state store inconsistencies between job and scaling_policy tables.","solutions":["Check the wrapped cause in server logs","Retry the job register (atomic rollback means no half-applied policies)","Compare scaling_policy table entries vs the job spec via API and reconcile with a re-submit","Upgrade Nomad if reproducible on your version"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate scaling policy block before submitting\nfor _, tg := range job.TaskGroups {\n  if tg.Scaling != nil && (tg.Scaling.Max < tg.Scaling.Min) {\n    return fmt.Errorf(\"task group %s: scaling.max < scaling.min\", tg.Name)\n  }\n}","typeGuard":"func isScalingPolicyError(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"job scaling policies\")\n}","tryCatchPattern":"_, err := client.Jobs().Register(job, nil, nil, nil)\nif isScalingPolicyError(err) {\n  // inspect existing policies then resubmit\n  policies, _, _ := client.Scaling().ListPolicies(nil)\n  _ = policies\n  _, err = client.Jobs().Register(job, nil, nil, nil)\n}\nreturn err","preventionTips":["Keep scaling policy IDs stable when updating jobs","List existing scaling policies before resubmitting scaled jobs","Avoid renaming task groups with active scaling policies","Upgrade servers as a set to avoid table schema mismatches"],"tags":["nomad","state-store","scaling-policies"],"backgroundTag":"scaling-policy-sync-failed","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"}