hashicorp/nomad · error

Missing constraint operand

Error message

Missing constraint operand

What it means

Constraint.Validate() appends this error when the constraint's Operand field is empty. The operand defines the comparison operator (=, !=, regexp, set_contains, etc.) and is required for Nomad to interpret the constraint; without it the constraint is meaningless and rejected.

Source

Thrown at nomad/structs/structs.go:10057

func (c *Constraint) Copy() *Constraint {
	if c == nil {
		return nil
	}
	return &Constraint{
		LTarget: c.LTarget,
		RTarget: c.RTarget,
		Operand: c.Operand,
	}
}

func (c *Constraint) String() string {
	return fmt.Sprintf("%s %s %s", c.LTarget, c.Operand, c.RTarget)
}

func (c *Constraint) Validate() error {
	var mErr multierror.Error
	if c.Operand == "" {
		mErr.Errors = append(mErr.Errors, errors.New("Missing constraint operand"))
	}

	// requireLtarget specifies whether the constraint requires an LTarget to be
	// provided.
	requireLtarget := true

	// Perform additional validation based on operand
	switch c.Operand {
	case ConstraintDistinctHosts:
		requireLtarget = false
	case ConstraintSetContainsAll, ConstraintSetContainsAny, ConstraintSetContains:
		if c.RTarget == "" {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Set contains constraint requires an RTarget"))
		}
	case ConstraintRegex:
		if _, err := regexp.Compile(c.RTarget); err != nil {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Regular expression failed to compile: %v", err))
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set the constraint operator explicitly, e.g. constraint { attribute = "${meta.rack}"; value = "r1" } which sets operand "="; or set Operand = "=" in Go.
  2. If building via JSON API, ensure the constraint object's Operand key is populated (canonicalize/parse normally sets "=" for HCL).
  3. Remove the empty constraint stanza entirely if it was unintentional.
  4. Use `nomad job validate` to catch it before submission.

Example fix

// before (Go)
c := &structs.Constraint{LTarget: "${meta.rack}", RTarget: "r1"}
// after
c := &structs.Constraint{LTarget: "${meta.rack}", RTarget: "r1", Operand: "="}
Defensive patterns

Strategy: validation

Validate before calling

func validateConstraintOperand(c *structs.Constraint) error {
	if c.Operand == "" {
		return fmt.Errorf("constraint %q: operand is required", c.LTarget)
	}
	return nil
}

Type guard

func hasOperand(c *structs.Constraint) bool { return c != nil && c.Operand != "" }

Prevention

When it happens

Trigger: Submitting a job/group/task constraint stanza with no operator — in HCL, writing only `attribute = "..."` and `value = "..."` without `operator`; in Go, constructing Constraint{LTarget, RTarget} and leaving Operand "" before Validate.

Common situations: Users assuming '=' is implied like in some tools (in Nomad HCL, `attr = value` sets operand implicitly, but raw JSON/API construction misses it); programmatic job builders copying fields selectively; API consumers migrating from other schedulers' filter syntax.

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