hashicorp/nomad · error
Set contains constraint requires an RTarget
Error message
Set contains constraint requires an RTarget
What it means
Constraints using set-contains operands (set_contains, set_contains_all, set_contains_any) require a non-empty RTarget listing the set membership values to check against. An empty RTarget makes the constraint meaningless, so validation fails.
Source
Thrown at nomad/structs/structs.go:10070
}
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))
}
case ConstraintVersion:
if _, err := version.NewConstraint(c.RTarget); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Version constraint is invalid: %v", err))
}
case ConstraintSemver:
if _, err := semver.NewConstraint(c.RTarget); err != nil {
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 {View on GitHub (pinned to 482b49bf1a)
Solutions
- Add a value listing items, e.g. constraint { operand = "set_contains", attribute = "${meta.roles}", value = "web" }.
- Remove the constraint if it is not needed.
- Check job-submission code paths so the RTarget is always populated for set-contains operands.
Example fix
// before
constraint {
operand = "set_contains"
attribute = "${node.meta.roles}"
}
// after
constraint {
operand = "set_contains"
attribute = "${node.meta.roles}"
value = "web"
} Defensive patterns
Strategy: validation
Validate before calling
if operand == "set_contains" || operand == "set_contains_all" || operand == "set_contains_any" {
if value == "" { return errors.New("set-contains constraint requires a value") }
} Prevention
- Always set 'value' for set-contains constraints
- Check generated HCL for dropped fields
- Test job validation (nomad job validate) in CI
When it happens
Trigger: constraint { operand = "set_contains" } with no 'value'/'rtarget' field set, or value = "" — e.g. generated HCL where the attribute was dropped.
Common situations: Programmatic job generation omitting the value for set-contains constraints; hand-written constraints copying the distinct_hosts form (which needs no ltarget/rtarget pair semantics); refactors that rename fields and lose the value.
Related errors
- Disconnect cannot be configured with both lost_after and sto
- lost_after cannot be a negative duration
- stop_after cannot be a negative duration
- Missing job ID
- Job ID contains a space
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/46f08ac012f2f570.
Report an issue: GitHub.