hashicorp/nomad · error
System jobs may not have an affinity block
Error message
System jobs may not have an affinity block
What it means
Job.Validate() rejects system jobs that declare any affinities: 'System jobs may not have an affinity block'. Affinities influence placement scoring among candidate nodes, which is meaningless for system jobs since they run on every eligible node.
Source
Thrown at nomad/structs/structs.go:4787
for _, v := range j.Datacenters {
if v == "" {
mErr.Errors = append(mErr.Errors, errors.New("Job datacenter must be non-empty string"))
}
}
}
if len(j.TaskGroups) == 0 {
mErr.Errors = append(mErr.Errors, errors.New("Missing job task groups"))
}
for idx, constr := range j.Constraints {
if err := constr.Validate(); err != nil {
outer := fmt.Errorf("Constraint %d validation failed: %s", idx+1, err)
mErr.Errors = append(mErr.Errors, outer)
}
}
if j.Type == JobTypeSystem {
if j.Affinities != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("System jobs may not have an affinity block"))
}
} else {
for idx, affinity := range j.Affinities {
if err := affinity.Validate(); err != nil {
outer := fmt.Errorf("Affinity %d validation failed: %s", idx+1, err)
mErr.Errors = append(mErr.Errors, outer)
}
}
}
if j.Type == JobTypeSystem {
if j.Spreads != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("System jobs may not have a spread block"))
}
} else {
for idx, spread := range j.Spreads {
if err := spread.Validate(); err != nil {
outer := fmt.Errorf("Spread %d validation failed: %s", idx+1, err)View on GitHub (pinned to 482b49bf1a)
Solutions
- Remove all affinity blocks from the system job spec
- If placement preference is needed, use node constraints (constraint blocks) with node_class/meta attributes instead
- Keep affinities only on service/batch jobs
- Run 'nomad job validate' to confirm the corrected spec
Example fix
// before
job "sys" {
type = "system"
affinity {
attribute = "${node.datacenter}"
value = "dc1"
}
}
// after
job "sys" {
type = "system"
constraint {
attribute = "${node.datacenter}"
value = "dc1"
}
} Defensive patterns
Strategy: validation
Validate before calling
if job.Type == "system" && len(job.Affinities) > 0 {
return errors.New("system jobs may not declare affinities")
}
return nil Try / catch
if err := job.Validate(); err != nil {
if strings.Contains(err.Error(), "affinity block") {
return ErrSystemJobAffinity
}
return err
} Prevention
- When changing job type to system, strip affinity and spread blocks
- Maintain separate job templates for system vs service jobs
- Lint job specs for affinity blocks when type=system
When it happens
Trigger: Registering or validating a job with type = "system" (j.Type == JobTypeSystem) while j.Affinities is non-nil, i.e. the job spec contains an affinity block at job or group level.
Common situations: Converting a service job to a system job without removing its affinity blocks, copy-pasting a service job template, or an HCL job where affinity blocks were left in place after changing the scheduler type.
Related errors
- System jobs may not have a spread block
- Job task group %s has count %d. Count cannot exceed 1 with s
- Set contains operators require an RTarget
- Version affinity is invalid: %v
- ErrConnectRequireOneNetwork
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/76e35fd0f8c0f380.
Report an issue: GitHub.