hashicorp/nomad · error

job summary insert failed: %v

Error message

job summary insert failed: %v

What it means

DeleteJobTxn (nomad/state/state_store.go:2008) wraps a failure from txn.Insert("job_summary", pSummary) after the parent job summary counters were modified while deleting a child job. The summary write failed so the deregistration transaction aborts and rolls back; the wrapped %v carries the underlying txn.Insert cause.

Source

Thrown at nomad/state/state_store.go:2008

					pSummary.Children.Pending--
					pSummary.Children.Dead++
					modified = true
				case structs.JobStatusRunning:
					pSummary.Children.Running--
					pSummary.Children.Dead++
					modified = true
				case structs.JobStatusDead:
				default:
					return fmt.Errorf("unknown old job status %q", job.Status)
				}

				if modified {
					// Update the modify index
					pSummary.ModifyIndex = index

					// Insert the summary
					if err := txn.Insert("job_summary", pSummary); err != nil {
						return fmt.Errorf("job summary insert failed: %v", err)
					}
					if err := txn.Insert("index", &IndexEntry{"job_summary", index}); err != nil {
						return fmt.Errorf("index update failed: %v", err)
					}
				}
			}
		}
	}

	// Delete the job
	if err := txn.Delete("jobs", existing); err != nil {
		return fmt.Errorf("job delete failed: %v", err)
	}
	if err := txn.Insert("index", &IndexEntry{"jobs", index}); err != nil {
		return fmt.Errorf("index update failed: %v", err)
	}

	// Delete the job versions

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Retry the deregistration; the failed txn rolled back
  2. Read the wrapped %v error in server logs to find the root cause
  3. Restart the server agent to rebuild state from Raft
  4. If tied to a snapshot restore, re-verify snapshot integrity

Example fix

// before
err := s.DeleteJobTxn(idx, ns, jobID, txn)
// after
if err := s.DeleteJobTxn(idx, ns, jobID, txn); err != nil {
    if strings.Contains(err.Error(), "job summary insert failed") {
        return retry(func() error { return s.DeleteJobTxn(idx, ns, jobID, txn) })
    }
    return err
}
Defensive patterns

Strategy: retry

Validate before calling

// ensure the parent summary exists and is well-formed before child delete
if job.ParentID != "" {
    sum, err := stateStore.JobSummaryByID(nil, ns, job.ParentID)
    if err != nil { return err }
    if sum != nil && sum.Children == nil {
        return fmt.Errorf("parent summary for %s has nil Children; state is inconsistent", job.ParentID)
    }
}

Type guard

func validSummary(x interface{}) bool { s, ok := x.(*structs.JobSummary); return ok && s != nil && s.Children != nil }

Try / catch

if err := s.DeleteJobTxn(idx, ns, jobID, txn); err != nil {
    if strings.Contains(err.Error(), "job summary insert failed") {
        return retry(3, backoff, func() error { return s.DeleteJobTxn(idx, ns, jobID, txn) })
    }
    return err
}

Prevention

When it happens

Trigger: Deleting a dispatched/periodic child whose parent summary was modified, and txn.Insert on the job_summary table fails (invalid summary object, MemDB error, aborted transaction).

Common situations: In-memory DB issues on the server applying the deregistration; corrupted JobSummary entries restored from a bad snapshot; concurrent modifications breaking assumptions within the txn.

Related errors


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