hashicorp/nomad · error
Version affinity is invalid: %v
Error message
Version affinity is invalid: %v
What it means
An affinity with operand "version" has an RTarget that hashicorp/go-version's NewConstraint cannot parse. Unlike the constraint counterpart, the message says "Version affinity", but the cause is identical: the version expression is malformed. Job submission is rejected by validation.
Source
Thrown at nomad/structs/structs.go:10212
func (a *Affinity) Validate() error {
var mErr multierror.Error
if a.Operand == "" {
mErr.Errors = append(mErr.Errors, errors.New("Missing affinity operand"))
}
// Perform additional validation based on operand
switch a.Operand {
case ConstraintSetContainsAll, ConstraintSetContainsAny, ConstraintSetContains:
if a.RTarget == "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Set contains operators require an RTarget"))
}
case ConstraintRegex:
if _, err := regexp.Compile(a.RTarget); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Regular expression failed to compile: %v", err))
}
case ConstraintVersion:
if _, err := version.NewConstraint(a.RTarget); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Version affinity is invalid: %v", err))
}
case ConstraintSemver:
if _, err := semver.NewConstraint(a.RTarget); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Semver affinity is invalid: %v", err))
}
case "=", "==", "is", "!=", "not", "<", "<=", ">", ">=":
if a.RTarget == "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Operator %q requires an RTarget", a.Operand))
}
default:
mErr.Errors = append(mErr.Errors, fmt.Errorf("Unknown affinity operator %q", a.Operand))
}
// Ensure we have an LTarget
if a.LTarget == "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("No LTarget provided but is required"))
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Rewrite the RTarget in valid go-version syntax, e.g. ">= 1.2.0" or ">= 1.2, < 2.0".
- Pre-validate with version.NewConstraint(target) before submission.
- Use nomad job validate to catch the malformed expression early.
Example fix
// before
affinity {
attribute = "${attr.driver.docker.version}"
operand = "version"
value = ">= 20.10.x"
}
// after
affinity {
attribute = "${attr.driver.docker.version}"
operand = "version"
value = ">= 20.10.0"
} Defensive patterns
Strategy: validation
Validate before calling
import "github.com/hashicorp/go-version"
func validAffinityVersion(target string) bool {
_, err := version.NewConstraint(target)
return err == nil
} Try / catch
if _, err := version.NewConstraint(target); err != nil {
return fmt.Errorf("invalid version affinity %q: %w", target, err)
} Prevention
- Use go-version range grammar only; no npm/cargo range syntax.
- Sanitize templated version strings for stray commas/whitespace.
- Run nomad job validate in the deployment pipeline.
When it happens
Trigger: Submitting an affinity with operand "version" and RTarget like ">= 1.x.y!", "1.2.3.4", "v>= 1.2 ," (trailing comma), or other malformed comparator lists.
Common situations: Typos in version ranges in templated jobs; concatenating version strings programmatically producing invalid expressions; using SemVer-only or npm-style range syntax unsupported by go-version; copy-paste with stray whitespace/commas.
Related errors
- System jobs may not have an affinity block
- Version constraint is invalid: %v
- Set contains operators require an RTarget
- ErrConnectRequireOneNetwork
- ErrConnectInvalidNetworkMode
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/d81d62930eaa0c92.
Report an issue: GitHub.