hashicorp/nomad · error

job %q in namespace %q at version %d not found

Error message

job %q in namespace %q at version %d not found

What it means

After confirming the job exists at some version, Revert looks up the specific historical version via snap.JobByIDAndVersion. If that (namespace, job ID, version) triple is absent from the version history it returns "job %q in namespace %q at version %d not found". Nomad keeps a bounded version history, so old versions can be gone even though the job itself exists.

Source

Thrown at nomad/job_endpoint.go:589

	}
	ws := memdb.NewWatchSet()
	cur, err := snap.JobByID(ws, args.RequestNamespace(), args.JobID)
	if err != nil {
		return err
	}
	if cur == nil {
		return fmt.Errorf("job %q not found", args.JobID)
	}
	if args.JobVersion == cur.Version {
		return fmt.Errorf("can't revert to current version")
	}

	jobV, err := snap.JobByIDAndVersion(ws, args.RequestNamespace(), args.JobID, args.JobVersion)
	if err != nil {
		return err
	}
	if jobV == nil {
		return fmt.Errorf("job %q in namespace %q at version %d not found", args.JobID, args.RequestNamespace(), args.JobVersion)
	}

	// Build the register request
	revJob := jobV.Copy()

	// Clear out the VersionTag to prevent tag duplication
	revJob.VersionTag = nil

	// Set the stable flag to false as this is functionally a new registration
	// and should handle deployment updates
	revJob.Stable = false

	reg := &structs.JobRegisterRequest{
		Job:          revJob,
		WriteRequest: args.WriteRequest,
	}

	// If the request is enforcing the existing version do a check.

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. List available versions (`nomad job history <id>` or job versions API) and pick an existing version
  2. Use the job's Versions list from the inspect/status API to validate the target version before calling Revert
  3. If the needed version was pruned, re-register the desired job specification from source control instead of reverting
  4. Correct the version number in the script/CLI invocation

Example fix

// before (blind revert)
client.Jobs().Revert("webapp", cur, 99, nil, nil, nil)
// after (validate version exists)
versions, _, _ := client.Jobs().Versions("webapp", false, nil)
for _, v := range versions {
    if *v.Version == 99 {
        client.Jobs().Revert("webapp", cur, 99, nil, nil, nil)
        break
    }
}
Defensive patterns

Strategy: validation

Validate before calling

versions, _, err := client.Jobs().Versions(jobID, false, nil)
if err != nil { return err }
found := false
for _, v := range versions { if *v.Version == targetVersion { found = true } }
if !found { return fmt.Errorf("version %d not in history for %s", targetVersion, jobID) }

Type guard

func versionInHistory(versions []*api.Job, target uint64) bool {
    for _, v := range versions { if v.Version != nil && *v.Version == target { return true } }
    return false
}

Try / catch

_, _, err := client.Jobs().Revert(jobID, cur, target, nil, nil, wo)
if err != nil && strings.Contains(err.Error(), "at version") {
    // version missing from history: fall back to re-registering the spec
}

Prevention

When it happens

Trigger: Calling Job.Revert with a JobVersion that was never registered, or one that has aged out of the retained version history (Nomad prunes job versions per job), while the job itself still exists.

Common situations: Reverting to a version number beyond the retained history after many deploys; guessing version numbers in scripts; referencing a version from before a job was purged and re-registered (versions restart); typos in the version number.

Related errors


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