{"record":{"id":"63197edee2d0bf1c","repo":"hashicorp/nomad","slug":"constraint-d-validation-failed-using-unsupported","errorCode":null,"errorMessage":"Constraint %d validation failed: using unsupported operand %q","messagePattern":"Constraint (.+?) validation failed: using unsupported operand %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":3139,"sourceCode":"\t\t}\n\t}\n}\n\nfunc (r *RequestedDevice) Validate() error {\n\tif r == nil {\n\t\treturn nil\n\t}\n\n\tvar mErr multierror.Error\n\tif r.Name == \"\" {\n\t\t_ = multierror.Append(&mErr, errors.New(\"device name must be given as one of the following: type, vendor/type, or vendor/type/name\"))\n\t}\n\n\tfor idx, constr := range r.Constraints {\n\t\t// Ensure that the constraint doesn't use an operand we do not allow\n\t\tswitch constr.Operand {\n\t\tcase ConstraintDistinctHosts, ConstraintDistinctProperty:\n\t\t\touter := fmt.Errorf(\"Constraint %d validation failed: using unsupported operand %q\", idx+1, constr.Operand)\n\t\t\t_ = multierror.Append(&mErr, outer)\n\t\tdefault:\n\t\t\tif err := constr.Validate(); err != nil {\n\t\t\t\touter := fmt.Errorf(\"Constraint %d validation failed: %s\", idx+1, err)\n\t\t\t\t_ = multierror.Append(&mErr, outer)\n\t\t\t}\n\t\t}\n\t}\n\tfor idx, affinity := range r.Affinities {\n\t\tif err := affinity.Validate(); err != nil {\n\t\t\touter := fmt.Errorf(\"Affinity %d validation failed: %s\", idx+1, err)\n\t\t\t_ = multierror.Append(&mErr, outer)\n\t\t}\n\t}\n\n\treturn mErr.ErrorOrNil()\n}\n","sourceCodeStart":3121,"sourceCodeEnd":3157,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L3121-L3157","documentation":"When validating a TaskGroup (or task resources struct), Nomad wraps constraint validation failures and explicitly rejects constraints using operands reserved for system-level handling: ConstraintDistinctHosts and ConstraintDistinctProperty. These operands are not permitted as ordinary constraints inside a job's constraint list.","triggerScenarios":"Adding a constraint { attribute = \"...\", operand = \"distinct_hosts\" } (or distinct_property) directly in a job/task-group constraints block and submitting via nomad job run or the jobs API.","commonSituations":"Copy-pasting spread/anti-affinity configuration from old job examples before distinct_hosts moved to its own field; writing JSON job specs by hand and using the operand in the wrong place.","solutions":["Remove the distinct_hosts/distinct_property constraint and use the dedicated distinct_hosts = true field or the spread stanza instead","If per-property spreading is needed, use the spread block rather than a constraint","Re-validate with nomad job validate after restructuring"],"exampleFix":"// before\nconstraint {\n  attribute = \"${node.unique.id}\"\n  operand   = \"distinct_hosts\"\n}\n// after\ndistinct_hosts = true","handlingStrategy":"validation","validationCode":"for _, c := range tg.Constraints {\n    if c.Operand == structs.ConstraintDistinctHosts || c.Operand == structs.ConstraintDistinctProperty {\n        return fmt.Errorf(\"use distinct_hosts field or spread stanza instead of operand %q\", c.Operand)\n    }\n}","typeGuard":"func isAllowedConstraintOperand(op string) bool {\n    switch op {\n    case structs.ConstraintDistinctHosts, structs.ConstraintDistinctProperty:\n        return false\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Use distinct_hosts = true and spread stanzas, never constraints with those operands","Run nomad job validate before submission","Keep job specs updated when upgrading Nomad (operands moved to dedicated fields)"],"tags":["nomad","constraint","validation","jobspec"],"backgroundTag":"unsupported-constraint-operand","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"}