hashicorp/nomad · error

job summary update failed %w

Error message

job summary update failed %w

What it means

This wrapper error is produced by setJobStatus when its call to s.setJobSummary(txn, updated, index, oldStatus, newStatus) fails; it chains the inner error with %w so errors.Is/As can inspect the cause (e.g. 'job summary insert failed' or 'unknown old job status'). The entire transaction, including the job status change, is rolled back. It signals the job's summary accounting could not be kept in sync with the new status.

Source

Thrown at nomad/state/state_store.go:5511

		return nil
	}

	// Copy and update the existing job
	updated := job.Copy()
	updated.Status = newStatus
	updated.ModifyIndex = index

	// Insert the job
	if err := txn.Insert("jobs", updated); 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)
	}

	// Update the children summary
	if err := s.setJobSummary(txn, updated, index, oldStatus, newStatus); err != nil {
		return fmt.Errorf("job summary update failed %w", err)
	}

	// Update the job version details. We need to make sure whenever the job summary
	// is updated, we also update the job's specific version. That way they do not
	// show different statuses.
	if err := s.upsertJobVersion(index, updated, txn); err != nil {
		return err
	}

	return nil
}

func (s *StateStore) setJobSummary(txn *txn, updated *structs.Job, index uint64, oldStatus, newStatus string) error {
	if updated.ParentID == "" {
		return nil
	}

	// Try to update the summary of the parent job summary

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Unwrap the %w chain (errors.Unwrap / %v in logs) to find the root cause
  2. Ensure only standard JobStatus values (pending/running/dead) are ever assigned to jobs
  3. Check for state corruption and restore from snapshot if needed
  4. Report upstream if the root cause is a Nomad bug

Example fix

// before (custom fork assigning nonstandard status)
updated.Status = "terminating"
// after
updated.Status = structs.JobStatusDead // only pending/running/dead are valid
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure only valid statuses are set on jobs before submit
if s := job.Status; s != "" && s != structs.JobStatusPending && s != structs.JobStatusRunning && s != structs.JobStatusDead {
    return fmt.Errorf("invalid job status %q", s)
}

Type guard

func isValidJobStatus(s string) bool {
    switch s {
    case "", structs.JobStatusPending, structs.JobStatusRunning, structs.JobStatusDead:
        return true
    }
    return false
}

Try / catch

if err != nil {
    var inner error
    errors.As(err, &inner) // %w chain: inspect root cause (e.g. unknown job status)
    return fmt.Errorf("job status change aborted: %w", err)
}

Prevention

When it happens

Trigger: A job status transition triggers setJobSummary, which itself fails (parent summary lookup error, unknown old/new status string, or summary insert failure), and setJobStatus wraps that failure with this message.

Common situations: Custom/patched status strings (e.g. plugins or forks injecting non-standard job statuses), state corruption, or internal bugs in summary accounting.

Related errors


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