hashicorp/nomad · error
can't revert to current version
Error message
can't revert to current version
What it means
Revert refuses a no-op rollback: after looking up the current job it compares the requested JobVersion to the job's currently registered version, and if they are equal returns "can't revert to current version". The endpoint exists to move a job to a *different* version, so reverting to the version already running is rejected explicitly.
Source
Thrown at nomad/job_endpoint.go:581
if args.JobID == "" {
return fmt.Errorf("missing job ID for revert")
}
// Lookup the job by version
snap, err := j.srv.fsm.State().Snapshot()
if err != nil {
return err
}
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 updatesView on GitHub (pinned to 482b49bf1a)
Solutions
- Check the current version first (`nomad job inspect <id>` → Job.Version) and only call Revert if the target differs
- If the desired config is already live, do nothing — the revert is complete
- Re-fetch job state after prior operations before issuing the revert to avoid stale version numbers
- Handle the error idempotently in scripts: treat it as success when the target version is already current
Example fix
// before
job, _ := client.Jobs().Info("webapp", nil)
client.Jobs().Revert("webapp", *job.Version, 5, nil, nil, nil)
// after
cur := *job.Version
if cur != 5 {
client.Jobs().Revert("webapp", cur, 5, nil, nil, nil)
} Defensive patterns
Strategy: validation
Validate before calling
cur, _, err := client.Jobs().Info(jobID, qo)
if err == nil && *cur.Version == targetVersion {
return nil // already at target; revert is a no-op
} Type guard
func isNoOpRevert(currentVersion, targetVersion uint64) bool { return currentVersion == targetVersion } Try / catch
_, _, err := client.Jobs().Revert(jobID, cur, target, nil, nil, wo)
if err != nil && strings.Contains(err.Error(), "can't revert to current version") {
return nil // idempotent success: target already live
} Prevention
- Fetch current version immediately before each revert
- Make revert scripts idempotent by short-circuiting on equal versions
- Re-check state after any concurrent deploy step in CI
When it happens
Trigger: Calling Job.Revert with args.JobVersion equal to cur.Version — i.e. the target version of the revert is the same as the job's currently registered version. E.g. `nomad job revert <id> <current-version-number>`.
Common situations: Scripting reverts with stale version numbers after someone already re-deployed; race where another operator reverted first; CI retry re-running a revert that already succeeded; hard-coding a version that happens to be the current one.
Related errors
- incompatible state version. expected %q but found %q
- missing job ID for revert
- job %q not found
- job %q in namespace %q at version %d not found
- Current job has version %d; enforcing version %d
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/f179ada3d0b050b0.
Report an issue: GitHub.