hashicorp/nomad · error
Unknown affinity operator %q
Error message
Unknown affinity operator %q
What it means
Affinity.Validate() only accepts a fixed set of operands: semver, version, =, ==, is, !=, not, <, <=, >, >=. Any other operand hits the default case and produces 'Unknown affinity operator %q'. This catches misspelled or unsupported operators before job registration.
Source
Thrown at nomad/structs/structs.go:10223
}
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"))
}
// Ensure that weight is between -100 and 100, and not zero
if a.Weight == 0 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Affinity weight cannot be zero"))
}
if a.Weight > 100 || a.Weight < -100 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Affinity weight must be within the range [-100,100]"))
}
return mErr.ErrorOrNil()
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Use one of the supported operators: version, semver, =, ==, is, !=, not, <, <=, >, >=.
- If you need regex/set matching, note those exist only for constraints, not affinities; restructure using a supported operator or move the check into a constraint.
- Check the Nomad docs version you target — operator support may differ across versions.
Example fix
// before
affinity {
attribute = "${meta.runtime}"
operator = "contains"
value = "java"
}
// after
affinity {
attribute = "${meta.runtime}"
operator = "is"
value = "java"
} Defensive patterns
Strategy: validation
Validate before calling
allowed := map[string]bool{"version":true,"semver":true,"=":true,"==":true,"is":true,"!=":true,"not":true,"<":true,"<=":true,">":true,">=":true}
if !allowed[a.Operand] { return fmt.Errorf("unsupported affinity operator %q", a.Operand) } Prevention
- Keep a whitelist of supported affinity operators in your job-spec tooling
- Remember constraint-only operators (regexp, set_contains) are invalid on affinities
- Run nomad job validate in CI before deployment
When it happens
Trigger: Submitting a job with an affinity whose operand is not in the allowed set, e.g. operator = "regex", "contains", "~>", or a misspelling like "equals" in the affinity block or the /v1/jobs API payload.
Common situations: Confusing constraint operators with affinity operators (some constraint-only operators like regexp/set_contains are invalid for affinities), typos, or copying a constraint block into an affinity block without adjusting the operator.
Related errors
- Semver affinity is invalid: %v
- No LTarget provided but is required
- Affinity weight cannot be zero
- Affinity weight must be within the range [-100,100]
- Disconnect cannot be configured with both lost_after and sto
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0e6d5a3fc64b4c85.
Report an issue: GitHub.