{"record":{"id":"0e6d5a3fc64b4c85","repo":"hashicorp/nomad","slug":"unknown-affinity-operator-q","errorCode":null,"errorMessage":"Unknown affinity operator %q","messagePattern":"Unknown affinity operator %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":10223,"sourceCode":"\t\t}\n\tcase ConstraintRegex:\n\t\tif _, err := regexp.Compile(a.RTarget); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Regular expression failed to compile: %v\", err))\n\t\t}\n\tcase ConstraintVersion:\n\t\tif _, err := version.NewConstraint(a.RTarget); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Version affinity is invalid: %v\", err))\n\t\t}\n\tcase ConstraintSemver:\n\t\tif _, err := semver.NewConstraint(a.RTarget); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Semver affinity is invalid: %v\", err))\n\t\t}\n\tcase \"=\", \"==\", \"is\", \"!=\", \"not\", \"<\", \"<=\", \">\", \">=\":\n\t\tif a.RTarget == \"\" {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Operator %q requires an RTarget\", a.Operand))\n\t\t}\n\tdefault:\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Unknown affinity operator %q\", a.Operand))\n\t}\n\n\t// Ensure we have an LTarget\n\tif a.LTarget == \"\" {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"No LTarget provided but is required\"))\n\t}\n\n\t// Ensure that weight is between -100 and 100, and not zero\n\tif a.Weight == 0 {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Affinity weight cannot be zero\"))\n\t}\n\n\tif a.Weight > 100 || a.Weight < -100 {\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Affinity weight must be within the range [-100,100]\"))\n\t}\n\n\treturn mErr.ErrorOrNil()\n}","sourceCodeStart":10205,"sourceCodeEnd":10241,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L10205-L10241","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\naffinity {\n  attribute = \"${meta.runtime}\"\n  operator  = \"contains\"\n  value     = \"java\"\n}\n// after\naffinity {\n  attribute = \"${meta.runtime}\"\n  operator  = \"is\"\n  value     = \"java\"\n}","handlingStrategy":"validation","validationCode":"allowed := map[string]bool{\"version\":true,\"semver\":true,\"=\":true,\"==\":true,\"is\":true,\"!=\":true,\"not\":true,\"<\":true,\"<=\":true,\">\":true,\">=\":true}\nif !allowed[a.Operand] { return fmt.Errorf(\"unsupported affinity operator %q\", a.Operand) }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["nomad","affinity","job-spec","validation"],"backgroundTag":"invalid-operator","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}