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
- Read the wrapped cause from server logs
- Retry the job registration after confirming server health
- Delete stale recommendations for the job before re-registering
- 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
- Apply or delete outstanding recommendations before restructuring task groups
- Avoid renaming task groups on jobs with stored recommendations
- Only enable recommendations (optimizer) on consistent cluster versions
- Monitor optimizer API errors in server logs
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
- error parsing: root should be an object
- cannot specify Accessor ID
- network already configured but not found in state
- eval not found
- deployment promotion cannot be undone
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/43ba87df9c3518c3.
Report an issue: GitHub.