{"record":{"id":"05de479f197040ee","repo":"hashicorp/nomad","slug":"constraint-d-has-disallowed-operand-at-task-level","errorCode":null,"errorMessage":"Constraint %d has disallowed Operand at task level: %s","messagePattern":"Constraint (.+?) has disallowed Operand at task level: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":8293,"sourceCode":"\t}\n\n\t// Validate the log config\n\tif t.LogConfig == nil {\n\t\tmErr.Errors = append(mErr.Errors, errors.New(\"Missing Log Config\"))\n\t} else if err := t.LogConfig.Validate(tg.EphemeralDisk); err != nil {\n\t\tmErr.Errors = append(mErr.Errors, err)\n\t}\n\n\t// Validate constraints and affinities.\n\tfor idx, constr := range t.Constraints {\n\t\tif err := constr.Validate(); err != nil {\n\t\t\touter := fmt.Errorf(\"Constraint %d validation failed: %s\", idx+1, err)\n\t\t\tmErr.Errors = append(mErr.Errors, outer)\n\t\t}\n\n\t\tswitch constr.Operand {\n\t\tcase ConstraintDistinctHosts, ConstraintDistinctProperty:\n\t\t\touter := fmt.Errorf(\"Constraint %d has disallowed Operand at task level: %s\", idx+1, constr.Operand)\n\t\t\tmErr.Errors = append(mErr.Errors, outer)\n\t\t}\n\t}\n\n\tif jobType == JobTypeSystem {\n\t\tif t.Affinities != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"System jobs may not have an affinity block\"))\n\t\t}\n\t} else {\n\t\tfor idx, affinity := range t.Affinities {\n\t\t\tif err := affinity.Validate(); err != nil {\n\t\t\t\touter := fmt.Errorf(\"Affinity %d validation failed: %s\", idx+1, err)\n\t\t\t\tmErr.Errors = append(mErr.Errors, outer)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate Services","sourceCodeStart":8275,"sourceCodeEnd":8311,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L8275-L8311","documentation":"Emitted in Task validation (nomad/structs/structs.go:8293) when a task-level constraint uses the DistinctHosts or DistinctProperty operand. These placement-counting constraints are only meaningful at the task-group level, so Nomad rejects them when declared on an individual task.","triggerScenarios":"task { constraint { operand = \"distinct_hosts\" } } or operand = \"distinct_property\" inside a task block; job submission or nomad job validate of that job.","commonSituations":"Users copy a group-level constraint into a task thinking it applies per task; misunderstanding Nomad's placement semantics where spread/distinct constraints are group-scoped.","solutions":["Move the constraint block from the task to the enclosing group block.","If per-task distinction is needed, use group-level distinct_property with ${meta.*} attributes or the spread stanza.","Validate with nomad job validate after moving the block."],"exampleFix":"// before\ntask \"app\" {\n  constraint { operand = \"distinct_hosts\" }\n}\n// after\ngroup \"g\" {\n  constraint { operand = \"distinct_hosts\" }\n  task \"app\" {}\n}","handlingStrategy":"validation","validationCode":"for i, c := range t.Constraints {\n  if c.Operand == \"distinct_hosts\" || c.Operand == \"distinct_property\" {\n    return fmt.Errorf(\"constraint %d: %s not allowed at task level; move to group\", i+1, c.Operand)\n  }\n}","typeGuard":"func isGroupOnlyOperand(op string) bool {\n  return op == \"distinct_hosts\" || op == \"distinct_property\"\n}","tryCatchPattern":null,"preventionTips":["Declare distinct_hosts/distinct_property only inside group blocks.","Use spread stanzas for fine-grained distribution.","Lint job files for operand placement."],"tags":["nomad","validation","constraints","placement"],"backgroundTag":"invalid-config-value","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"}