hashicorp/nomad · warning

tag %q not found on job %q

Error message

tag %q not found on job %q

What it means

Unsetting a job version tag requires that the tag actually exists on some version of the job. The state store looks the tag up via JobVersionByTagName and, when nothing is bound, rejects the unset request with this error instead of silently succeeding.

Source

Thrown at nomad/state/state_store.go:4969

	if err != nil {
		return err
	}
	if versionCopy.Version == latestJob.Version {
		if err := txn.Insert("jobs", versionCopy); err != nil {
			return err
		}
	}

	return s.upsertJobVersion(index, versionCopy, txn)
}

func (s *StateStore) unsetJobVersionTagImpl(index uint64, namespace, jobID string, name string, txn *txn) error {
	job, err := s.JobVersionByTagName(nil, namespace, jobID, name)
	if err != nil {
		return err
	}
	if job == nil {
		return fmt.Errorf("tag %q not found on job %q", name, jobID)
	}

	versionCopy := job.Copy()
	versionCopy.VersionTag = nil
	versionCopy.ModifyIndex = index
	latestJob, err := s.JobByID(nil, namespace, jobID)
	if err != nil {
		return err
	}
	if versionCopy.Version == latestJob.Version {
		if err := txn.Insert("jobs", versionCopy); err != nil {
			return err
		}
	}

	return s.upsertJobVersion(index, versionCopy, txn)
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check current tags via GET /v1/job/:jobId/versions before unsetting
  2. Treat this error as success in idempotent delete/cleanup flows
  3. Correct the tag name (case-sensitive) and retry

Example fix

// before: blindly DELETE tag=prod on every deploy
// after
if tags := versionsWithTags(jobVersions); tags.contains("prod") {
  unsetTag("prod")
} // else skip, already unset
Defensive patterns

Strategy: validation

Validate before calling

versions, _, _ := client.Jobs().Versions(jobID, false, nil)
tagged := false
for _, v := range versions {
  if v.VersionTag != nil && v.VersionTag.Name == name { tagged = true }
}
if !tagged { return nil } // nothing to unset

Try / catch

err := unsetTag(jobID, name)
if err != nil && strings.Contains(err.Error(), "not found") {
  return nil // already unset; idempotent success
}

Prevention

When it happens

Trigger: Calling the unset tag endpoint (DELETE /v1/job/:jobId/versions/tag?tag=NAME / JobRevert-related unset RPC) with a tag name that no version carries, or that was already unset.

Common situations: Idempotent cleanup scripts running twice; typos in tag names; tags already removed by another operator or automation between listing and deletion.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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