hashicorp/nomad · error

unable to update job recommendations: %v

Error message

unable to update job recommendations: %v

What it means

UpsertJob failed while updating job recommendations via updateJobRecommendations, which reconciles stored recommendations against the newly submitted job's task group resources. The failure wraps the internal error and aborts the registration transaction.

Source

Thrown at nomad/state/state_store.go:1896

		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)
	}

	// Insert the job
	if err := txn.Insert("jobs", job); err != nil {
		return fmt.Errorf("job insert failed: %v", err)
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the wrapped cause from server logs
  2. Retry the job registration after confirming server health
  3. Delete stale recommendations for the job before re-registering
  4. Disable/remove the recommendations workflow temporarily if it blocks critical registrations
Defensive patterns

Strategy: validation

Validate before calling

// Check for stale recommendations before re-registering a restructured job
recs, _, err := client.Recommendations().List(&nomad.QueryOptions{Namespace: job.Namespace})
if err == nil {
  for _, r := range recs {
    if r.Job == job.ID {
      fmt.Printf("stale recommendation for %s/%s\n", r.Job, r.TaskGroup)
    }
  }
}

Type guard

func isRecommendationError(err error) bool {
  return err != nil && strings.Contains(err.Error(), "job recommendations")
}

Try / catch

_, err := client.Jobs().Register(job, nil, nil, nil)
if isRecommendationError(err) {
  // retry; if persistent, apply/delete pending recommendations first
  _, err = client.Jobs().Register(job, nil, nil, nil)
}
return err

Prevention

When it happens

Trigger: Registering a job on a cluster using Nomad's Recommendations feature (enterprise/optimize) where recommendation table updates fail inside the transaction.

Common situations: Clusters using the optimizer/recommendations API where existing recommendations reference task groups that were renamed/removed in the new job spec.

Related errors


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