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

  1. Check the wrapped cause in server logs
  2. Retry the job register (atomic rollback means no half-applied policies)
  3. Compare scaling_policy table entries vs the job spec via API and reconcile with a re-submit
  4. 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

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/c89d0cde85866c0a. Report an issue: GitHub.