hashicorp/nomad · error

Operator %q requires an RTarget

Error message

Operator %q requires an RTarget

What it means

The constraint uses a comparison operator (=, ==, is, !=, not, <, <=, >, >=) but its RTarget (the value to compare the attribute against) is empty. These operators require a right-hand target, so validation rejects the job.

Source

Thrown at nomad/structs/structs.go:10100

			mErr.Errors = append(mErr.Errors, fmt.Errorf("Semver constraint is invalid: %v", err))
		}
	case ConstraintDistinctProperty:
		// If a count is set, make sure it is convertible to a uint64
		if c.RTarget != "" {
			count, err := strconv.ParseUint(c.RTarget, 10, 64)
			if err != nil {
				mErr.Errors = append(mErr.Errors, fmt.Errorf("Failed to convert RTarget %q to uint64: %v", c.RTarget, err))
			} else if count < 1 {
				mErr.Errors = append(mErr.Errors, fmt.Errorf("Distinct Property must have an allowed count of 1 or greater: %d < 1", count))
			}
		}
	case ConstraintAttributeIsSet, ConstraintAttributeIsNotSet:
		if c.RTarget != "" {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Operator %q does not support an RTarget", c.Operand))
		}
	case "=", "==", "is", "!=", "not", "<", "<=", ">", ">=":
		if c.RTarget == "" {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Operator %q requires an RTarget", c.Operand))
		}
	default:
		mErr.Errors = append(mErr.Errors, fmt.Errorf("Unknown constraint type %q", c.Operand))
	}

	// If the constraint must have a "LTarget" (attribute in the job spec), then
	// ensure it is not an empty string and is valid.
	if requireLtarget {
		if c.LTarget == "" {
			mErr.Errors = append(mErr.Errors, errors.New("no attribute provided but is required by operator"))
		} else {
			if err := validateConstraintAttribute(c.LTarget); err != nil {
				mErr.Errors = append(mErr.Errors, err)
			}
		}

	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add the missing value field to the constraint, e.g. value = "linux".
  2. Check that any variable interpolated into value is non-empty at render time.
  3. If no comparison is intended, switch the operand to is_set / is_not_set (which need no value).

Example fix

// before
constraint {
  attribute = "${attr.kernel.name}"
  operand   = "=="
}
// after
constraint {
  attribute = "${attr.kernel.name}"
  operand   = "=="
  value     = "linux"
}
Defensive patterns

Strategy: validation

Validate before calling

func constraintRequiresTarget(operand, rtarget string) bool {
  switch operand {
  case "=", "==", "is", "!=", "not", "<", "<=", ">", ">=":
    return rtarget != ""
  default:
    return true
  }
}

Try / catch

requires := []string{"=", "==", "is", "!=", "not", "<", "<=", ">", ">="}
if slices.Contains(requires, operand) && rtarget == "" {
  return fmt.Errorf("operator %q requires a value", operand)
}

Prevention

When it happens

Trigger: Submitting a constraint such as constraint { attribute = "${attr.kernel.name}" operand = "=" } with no value/RTarget supplied.

Common situations: HCL job spec missing the value field; templated generation where the variable interpolated into value was empty; accidental whitespace-only value trimmed away; copy-paste dropping the value line.

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/23ba4d7c3fd9ae16. Report an issue: GitHub.