hashicorp/nomad · error
unable to update job scaling policies: %v
Error message
unable to update job scaling policies: %v
What it means
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.
Source
Thrown at nomad/state/state_store.go:1892
updated, err := txn.First("jobs", "id", job.Namespace, job.ID)
if err != nil {
return fmt.Errorf("job lookup failed: %v", err)
}
if updated != nil {
job = updated.(*structs.Job)
}
}
if err := s.updateSummaryWithJob(index, job, txn); err != nil {
return fmt.Errorf("unable to create job summary: %v", err)
}
if err := s.upsertJobVersion(index, job, txn); err != nil {
return fmt.Errorf("unable to upsert job into job_version table: %v", err)
}
if err := s.updateJobScalingPolicies(index, job, txn); err != nil {
return fmt.Errorf("unable to update job scaling policies: %v", err)
}
if err := s.updateJobRecommendations(index, txn, existingJob, job); err != nil {
return fmt.Errorf("unable to update job recommendations: %v", err)
}
if err := s.updateJobCSIPlugins(index, job, existingJob, txn); err != nil {
return fmt.Errorf("unable to update job csi plugins: %v", err)
}
if err := s.updateJobSubmission(index, sub, job.Namespace, job.ID, job.Version, txn); err != nil {
return fmt.Errorf("unable to update job submission: %v", err)
}
if err := s.updatePreservedValues(job, existingJob, req); err != nil {
return fmt.Errorf("unable to update preserved values: %v", err)
}
View on GitHub (pinned to 482b49bf1a)
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
Defensive patterns
Strategy: validation
Validate before calling
// Validate scaling policy block before submitting
for _, tg := range job.TaskGroups {
if tg.Scaling != nil && (tg.Scaling.Max < tg.Scaling.Min) {
return fmt.Errorf("task group %s: scaling.max < scaling.min", tg.Name)
}
} Type guard
func isScalingPolicyError(err error) bool {
return err != nil && strings.Contains(err.Error(), "job scaling policies")
} Try / catch
_, err := client.Jobs().Register(job, nil, nil, nil)
if isScalingPolicyError(err) {
// inspect existing policies then resubmit
policies, _, _ := client.Scaling().ListPolicies(nil)
_ = policies
_, err = client.Jobs().Register(job, nil, nil, nil)
}
return err Prevention
- 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
When it happens
Trigger: Submitting a job that contains scaling policy blocks (or removing them) where the scaling-policy table write fails within the transaction.
Common situations: Jobs using the scaling stanza during cluster upgrades or with state store inconsistencies between job and scaling_policy tables.
Related errors
- getting job scaling policies for deletion failed: %v
- deleting scaling policy failed: %v
- ScalingPoliciesByJob lookup failed: %v
- DeleteScalingPolicies of removed policies failed: %v
- UpsertScalingPolicies of policies failed: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/c89d0cde85866c0a.
Report an issue: GitHub.