hashicorp/nomad · error
unable to update preserved values: %v
Error message
unable to update preserved values: %v
What it means
UpsertJob failed in updatePreservedValues, which copies multiregion/preserved fields (e.g. multiregion run settings, submit time/flags) from the existing job and request into the new job object before insertion. The wrapped error aborts the registration transaction.
Source
Thrown at nomad/state/state_store.go:1908
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)
}
if err := txn.Insert("index", &IndexEntry{"jobs", index}); err != nil {
return fmt.Errorf("index update failed: %v", err)
}
return nil
}
// CheckIdempotencyToken finds all children of the parent job ID and checks to
// make sure none of them were dispatched with the idempotency token passed as
// an argument. Returns the child job found, if any.
func (s *StateStore) CheckIdempotencyToken(ns, parentID, idempotencyToken string) (*structs.Job, error) {
iter, err := s.JobsByIDPrefix(nil, ns, parentID, SortDefault)View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped cause in server logs
- Retry the job registration
- Verify multiregion/authorization fields in the request (multiregion tokens/authorization) are set correctly
- Upgrade Nomad if reproducible on your version
Defensive patterns
Strategy: validation
Validate before calling
// Verify multiregion fields are complete before regional registration
if job.Multiregion != nil {
for _, r := range job.Multiregion.Regions {
if r.Region == "" || len(r.Datacenters) == 0 {
return fmt.Errorf("multiregion region entry missing region or datacenters")
}
}
} Type guard
func isPreservedValuesError(err error) bool {
return err != nil && strings.Contains(err.Error(), "preserved values")
} Try / catch
_, err := client.Jobs().Register(job, nil, nil, nil)
if isPreservedValuesError(err) {
// check multiregion authorization and retry
_, err = client.Jobs().Register(job, nil, nil, nil)
}
return err Prevention
- Send identical multiregion job specs to every region
- Ensure multiregion authorization tokens are valid when cross-registering
- Verify the existing job copy is readable (Jobs().Info) before updating
- Keep federated servers on consistent versions
When it happens
Trigger: Registering a job where preserving values from the existing job or request fails, typically tied to multiregion deployments or malformed request fields on the update path.
Common situations: Multiregion enterprise deployments, or federated clusters where the previous job copy is inconsistent during region failover.
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/48cd722a4af18294.
Report an issue: GitHub.