hashicorp/nomad · error
Missing job datacenters
Error message
Missing job datacenters
What it means
Job.Validate() requires at least one datacenter unless the job is multiregion. Datacenters constrain where the scheduler places allocations; with none specified the job cannot be placed, so the spec is invalid.
Source
Thrown at nomad/structs/structs.go:4767
}
if j.Name == "" {
mErr.Errors = append(mErr.Errors, errors.New("Missing job name"))
} else if strings.Contains(j.Name, "\000") {
mErr.Errors = append(mErr.Errors, errors.New("Job Name contains a null character"))
}
if j.Namespace == "" {
mErr.Errors = append(mErr.Errors, errors.New("Job must be in a namespace"))
}
switch j.Type {
case JobTypeCore, JobTypeService, JobTypeBatch, JobTypeSystem, JobTypeSysBatch:
case "":
mErr.Errors = append(mErr.Errors, errors.New("Missing job type"))
default:
mErr.Errors = append(mErr.Errors, fmt.Errorf("Invalid job type: %q", j.Type))
}
if len(j.Datacenters) == 0 && !j.IsMultiregion() {
mErr.Errors = append(mErr.Errors, errors.New("Missing job datacenters"))
} else {
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 {View on GitHub (pinned to 482b49bf1a)
Solutions
- Add `datacenters = ["dc1"]` (matching a datacenter your agents report) to the job file
- Convert the job to multiregion if it genuinely targets multiple regions
- Ensure job.Datacenters is populated when constructing the job in Go
Example fix
// before
job "web-app" {
type = "service"
group "web" { ... }
}
// after
job "web-app" {
type = "service"
datacenters = ["dc1"]
group "web" { ... }
} Defensive patterns
Strategy: validation
Validate before calling
if len(j.Datacenters) == 0 && !j.IsMultiregion() {
return fmt.Errorf("job must specify at least one datacenter")
} Type guard
func hasDatacenters(j *structs.Job) bool { return j.IsMultiregion() || len(j.Datacenters) > 0 } Try / catch
if err := job.Validate(); err != nil {
if strings.Contains(err.Error(), "Missing job datacenters") {
return fmt.Errorf("add datacenters = [\"dc1\"] to the job: %w", err)
}
} Prevention
- List datacenters matching nomad node status output
- Keep the datacenters stanza in all single-region job templates
- Run nomad job validate in CI
When it happens
Trigger: Submitting a job whose `datacenters` list is empty/absent and j.IsMultiregion() is false — via nomad job run, POST /v1/jobs, or Validate() on a programmatically built job.
Common situations: Forgetting `datacenters = ["dc1"]` when writing a job file; CLI-generated templates stripped of the stanza; jobs moved from a multiregion setup back to single-region without adding datacenters.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Job datacenter must be non-empty string
- Missing job ID
- Job ID contains a space
- Job ID contains a null character
- Missing job name
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/5fa6730f2425adac.
Report an issue: GitHub.