hashicorp/nomad · error

missing job ID for revert

Error message

missing job ID for revert

What it means

Nomad's Job.Revert RPC (nomad/job_endpoint.go:564) requires args.JobID to identify the job whose version is being reverted. When the request omits the job ID, the server cannot look up prior versions and rejects the call before touching state.

Source

Thrown at nomad/job_endpoint.go:564

	}
	defer metrics.MeasureSince([]string{"nomad", "job", "revert"}, time.Now())

	// Check for submit-job permissions
	aclObj, err := j.srv.ResolveACL(args)
	if err != nil {
		return err
	}

	if !aclObj.AllowNsOpAnyOf(args.RequestNamespace(),
		acl.NamespaceCapabilitySubmitJob,
		acl.NamespaceCapabilityRevertJob,
	) {
		return structs.ErrPermissionDenied
	}

	// Validate the arguments
	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")
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Provide the job ID: POST /v1/job/<job-id>/revert with {"JobVersion": N} or run `nomad job revert <job-id> <version>`.
  2. Confirm the job exists with `nomad job status` and use its exact ID (job IDs are case-sensitive and namespace-scoped).
  3. Fix templating/automation so the job ID variable is not empty in the revert call.
  4. If the job was purged, re-register it instead of attempting a revert; revert only works on jobs present in state.

Example fix

// before
curl -X POST http://localhost:4646/v1/job//revert -d '{"JobVersion": 2}'

// after
curl -X POST http://localhost:4646/v1/job/webapp/revert -d '{"JobVersion": 2}'
Defensive patterns

Strategy: validation

Validate before calling

if jobID == "" {
	return fmt.Errorf("jobID is required for revert; got %q from template", jobID)
}
if _, _, err := client.Jobs().Info(jobID, nil); err != nil {
	return fmt.Errorf("cannot revert unknown job %q: %w", jobID, err)
}

Type guard

func revertArgsValid(jobID string, version uint64) bool {
	return jobID != ""
}

Try / catch

_, _, err := client.Jobs().Revert(jobID, version, nil, nil)
if err != nil && strings.Contains(err.Error(), "missing job ID for revert") {
	return fmt.Errorf("revert called without job ID — check the jobID template variable: %w", err)
}

Prevention

When it happens

Trigger: Calling Job.Revert (POST /v1/job/<id>/revert or the CLI `nomad job revert`) with an empty JobID — e.g. building the RPC manually, or scripting the HTTP endpoint with an empty/missing path parameter.

Common situations: Automation that interpolates an empty job-name variable into the revert URL (/v1/job//revert); wrappers that pass only JobVersion without JobID; jobs deregistered but callers still attempting a revert with a blank identifier.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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