{"record":{"id":"2d2b1d5603259ad6","repo":"hashicorp/nomad","slug":"version-constraint-is-invalid-v","errorCode":null,"errorMessage":"Version constraint is invalid: %v","messagePattern":"Version constraint is invalid: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":10078,"sourceCode":"\t// requireLtarget specifies whether the constraint requires an LTarget to be\n\t// provided.\n\trequireLtarget := true\n\n\t// Perform additional validation based on operand\n\tswitch c.Operand {\n\tcase ConstraintDistinctHosts:\n\t\trequireLtarget = false\n\tcase ConstraintSetContainsAll, ConstraintSetContainsAny, ConstraintSetContains:\n\t\tif c.RTarget == \"\" {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Set contains constraint requires an RTarget\"))\n\t\t}\n\tcase ConstraintRegex:\n\t\tif _, err := regexp.Compile(c.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(c.RTarget); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Version constraint is invalid: %v\", err))\n\t\t}\n\tcase ConstraintSemver:\n\t\tif _, err := semver.NewConstraint(c.RTarget); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Semver constraint is invalid: %v\", err))\n\t\t}\n\tcase ConstraintDistinctProperty:\n\t\t// If a count is set, make sure it is convertible to a uint64\n\t\tif c.RTarget != \"\" {\n\t\t\tcount, err := strconv.ParseUint(c.RTarget, 10, 64)\n\t\t\tif err != nil {\n\t\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Failed to convert RTarget %q to uint64: %v\", c.RTarget, err))\n\t\t\t} else if count < 1 {\n\t\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Distinct Property must have an allowed count of 1 or greater: %d < 1\", count))\n\t\t\t}\n\t\t}\n\tcase ConstraintAttributeIsSet, ConstraintAttributeIsNotSet:\n\t\tif c.RTarget != \"\" {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Operator %q does not support an RTarget\", c.Operand))","sourceCodeStart":10060,"sourceCodeEnd":10096,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L10060-L10096","documentation":"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.","triggerScenarios":"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\".","commonSituations":"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.","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\"."],"exampleFix":"// before\nconstraint {\n  attribute = \"${attr.kernel.version}\"\n  version   = \">=1.2.x\"\n}\n// after\nconstraint {\n  attribute = \"${attr.kernel.version}\"\n  version   = \">= 1.2.0\"\n}","handlingStrategy":"validation","validationCode":"import \"github.com/hashicorp/go-version\"\n\nfunc validVersionConstraint(target string) bool {\n  _, err := version.NewConstraint(target)\n  return err == nil\n}\n// call before submitting: validVersionConstraint(c.RTarget)","typeGuard":null,"tryCatchPattern":"if _, err := version.NewConstraint(c.RTarget); err != nil {\n  return fmt.Errorf(\"invalid version constraint %q: %w\", c.RTarget, err)\n}","preventionTips":["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."],"tags":["nomad","constraint","version-parsing","job-validation"],"backgroundTag":"invalid-version-constraint","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"}