hashicorp/nomad · error
Version constraint is invalid: %v
Error message
Version constraint is invalid: %v
What it means
Nomad job constraint validation failed because the constraint's RTarget is not a parseable version constraint expression. Nomad uses hashicorp/go-version's NewConstraint to parse expressions like ">= 1.2, < 2.0". This error is collected into a multi-error and returned when Copy/Validate of a Constraint is called during job validation, so the job submission is rejected.
Source
Thrown at nomad/structs/structs.go:10078
// 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 {
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))View on GitHub (pinned to 482b49bf1a)
Solutions
- Fix the constraint RTarget to valid go-version syntax, e.g. ">= 1.2.0" or ">= 1.2, < 2.0".
- Pre-validate the expression in Go with version.NewConstraint(target) before submitting the job.
- If you need SemVer-only semantics (prerelease support), use operand "semver" instead of "version".
Example fix
// before
constraint {
attribute = "${attr.kernel.version}"
version = ">=1.2.x"
}
// after
constraint {
attribute = "${attr.kernel.version}"
version = ">= 1.2.0"
} Defensive patterns
Strategy: validation
Validate before calling
import "github.com/hashicorp/go-version"
func validVersionConstraint(target string) bool {
_, err := version.NewConstraint(target)
return err == nil
}
// call before submitting: validVersionConstraint(c.RTarget) Try / catch
if _, err := version.NewConstraint(c.RTarget); err != nil {
return fmt.Errorf("invalid version constraint %q: %w", c.RTarget, err)
} Prevention
- Always run `nomad job validate` before `nomad job run` in CI.
- Use go-version syntax docs as the single source for range grammar.
- For prerelease-aware matching, use the semver operand instead.
- Unit-test any templated constraint generation with round-trip parsing.
When it happens
Trigger: Submitting a job whose constraint has operand "version" and an RTarget that version.NewConstraint cannot parse, e.g. RTarget = ">=1.2.3-beta!" or "1..2" or empty-but-set garbage like "latest".
Common situations: Typo in the version expression in an HCL/JSON job spec; pasting a SemVer 2 prerelease expression into a version constraint (which only supports go-version syntax); upgrading Nomad with a stricter parser; programmatic job generation concatenating versions incorrectly.
Related errors
- 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
- Unknown constraint type %q
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/2d2b1d5603259ad6.
Report an issue: GitHub.