hashicorp/nomad · error
Unknown constraint type %q
Error message
Unknown constraint type %q
What it means
The constraint's Operand string does not match any operator Nomad recognizes (version, regex, is_set, comparison operators, set-contains, etc.), so it falls to the default case and is rejected as an unknown constraint type. Job submission fails validation.
Source
Thrown at nomad/structs/structs.go:10103
// 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)
}
}
}
return mErr.ErrorOrNil()
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Correct the operand to a supported one: =, ==, is, !=, not, <, <=, >, >=, version, regex, semver, set_contains, set_contains_any, set_contains_all, is_set, is_not_set, distinct_property.
- Use the job spec's sugar syntax (version = ">= 1.2", regexp = "...") instead of raw operands where possible.
- Run nomad job validate to catch the typo before submission.
Example fix
// before
constraint {
attribute = "${attr.kernel.version}"
operand = "verison"
value = ">= 4.4"
}
// after
constraint {
attribute = "${attr.kernel.version}"
version = ">= 4.4"
} Defensive patterns
Strategy: validation
Validate before calling
var validOperands = map[string]bool{
"=": true, "==": true, "is": true, "!=": true, "not": true,
"<": true, "<=": true, ">": true, ">=": true,
"version": true, "regex": true, "semver": true,
"set_contains": true, "set_contains_any": true, "set_contains_all": true,
"is_set": true, "is_not_set": true, "distinct_property": true,
}
func validOperand(op string) bool { return validOperands[op] } Try / catch
if !validOperands[operand] {
return fmt.Errorf("unknown constraint operand %q", operand)
} Prevention
- Keep a checked list of supported operands in your job-generation code.
- Prefer HCL sugar fields (version, regexp, semver) over raw operand strings.
- Run nomad job validate on every rendered job.
When it happens
Trigger: Submitting a job with a typo'd operand such as "verison", "Version", "between", or an operand removed/renamed in a newer Nomad version.
Common situations: Hand-written HCL with misspelled operand; migrating jobs between Nomad versions where an operand changed; using sugar fields (version/regexp/semver/distinct_property) incorrectly as operands; case-sensitivity mistakes.
Related errors
- Version constraint is invalid: %v
- Semver constraint is invalid: %v
- Distinct Property must have an allowed count of 1 or greater
- Operator %q does not support an RTarget
- Operator %q requires an RTarget
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/51e55cdba8f83b53.
Report an issue: GitHub.