hashicorp/nomad · error

tag %q not found

Error message

tag %q not found

What it means

Job.Scale or a diff request with DiffTagName set looked up a job version by tag name via state.JobVersionByTagName and got a nil result. The tag exists nowhere in the state store for that job/namespace, so Nomad cannot resolve it to a version number and aborts the request. This is a pre-flight existence check for the user-supplied tag reference.

Source

Thrown at nomad/job_endpoint.go:1284

			}

			// Setup the output
			reply.Versions = out
			if len(out) != 0 {

				var compareVersionNumber uint64
				var compareVersion *structs.Job
				var compareSpecificVersion bool

				if args.Diffs {
					if args.DiffTagName != "" {
						compareSpecificVersion = true
						compareVersion, err = state.JobVersionByTagName(ws, args.RequestNamespace(), args.JobID, args.DiffTagName)
						if err != nil {
							return fmt.Errorf("error looking up job version by tag: %v", err)
						}
						if compareVersion == nil {
							return fmt.Errorf("tag %q not found", args.DiffTagName)
						}
						compareVersionNumber = compareVersion.Version
					} else if args.DiffVersion != nil {
						compareSpecificVersion = true
						compareVersionNumber = *args.DiffVersion
					}
				}

				// Note: a previous assumption here was that the 0th job was the latest, and that we don't modify "old" versions.
				// Adding version tags breaks this assumption (you can tag an old version, which should unblock /versions queries) so we now look for the highest ModifyIndex.
				var maxModifyIndex uint64
				for _, job := range out {
					if job.ModifyIndex > maxModifyIndex {
						maxModifyIndex = job.ModifyIndex
					}
					if compareSpecificVersion && job.Version == compareVersionNumber {
						compareVersion = job
					}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. List the job's versions/tags (nomad job status -all-allocs / job versions API) and use an exact existing tag name.
  2. Verify you are querying the correct namespace; tags are scoped per namespace and job ID.
  3. Check for typos or case differences in DiffTagName.
  4. If the tag should exist, confirm the job was not purged/paused and re-tag the desired version.

Example fix

// before
args.DiffTagName = "prod"
// after
tags, _ := client.Jobs().Versions("my-job", false, nil) // inspect Tags per version
if !tagExists(tags, "prod") {
    args.DiffTagName = "" // fall back to DiffVersion or fix the name
}
Defensive patterns

Strategy: validation

Validate before calling

versions, _, err := client.Jobs().Versions(jobID, true, nil)
if err != nil { return err }
found := false
for _, v := range versions {
    for _, t := range v.Tags { if t == wantedTag { found = true } }
}
if !found { return fmt.Errorf("tag %q does not exist for job %s", wantedTag, jobID) }

Type guard

func tagExists(versions []*api.JobVersions, tag string) bool {
    for _, v := range versions { for _, t := range v.Tags { if t == tag { return true } } }
    return false
}

Prevention

When it happens

Trigger: Calling the job scale or plan/diff RPC with args.DiffTagName set to a tag that does not exist for args.JobID in args.RequestNamespace(). state.JobVersionByTagName returns (nil, nil) when no version carries that tag, hitting the `compareVersion == nil` branch at nomad/job_endpoint.go:1284.

Common situations: Typo in the tag name; tag was deleted when a job was stopped and purged; tag attached to a job in a different namespace; tooling assumes a tag was promoted when the promotion failed; querying before the tagged job version was ever registered.

Related errors


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