hashicorp/nomad · error
Task %s validation failed: %v
Error message
Task %s validation failed: %v
What it means
Produced during job validation when `task.Validate(j.Type, tg)` fails for a task inside a task group. Nomad wraps the task's own validation error as 'Task %s validation failed: %v' and appends it to the group multierror. It means one task's config (driver, resources, artifacts, services, templates, etc.) is invalid for the job's type.
Source
Thrown at nomad/structs/structs.go:7319
mErr = multierror.Append(mErr, outer)
}
// Validate group service script-checks
if err := tg.validateScriptChecksInGroupServices(); err != nil {
outer := fmt.Errorf("Task group service check validation failed: %v", err)
mErr = multierror.Append(mErr, outer)
}
// Validate the scaling policy
if err := tg.validateScalingPolicy(j); err != nil {
outer := fmt.Errorf("Task group scaling policy validation failed: %v", err)
mErr = multierror.Append(mErr, outer)
}
// Validate the tasks
for _, task := range tg.Tasks {
if err := task.Validate(j.Type, tg); err != nil {
outer := fmt.Errorf("Task %s validation failed: %v", task.Name, err)
mErr = multierror.Append(mErr, outer)
}
}
return mErr.ErrorOrNil()
}
func (tg *TaskGroup) validateNetworks() error {
var mErr multierror.Error
portLabels := make(map[string]string)
// host_network -> static port tracking
staticPortsIndex := make(map[string]map[int]string)
cniArgKeys := set.New[string](len(tg.Networks))
for _, net := range tg.Networks {
for _, port := range append(net.ReservedPorts, net.DynamicPorts...) {
if other, ok := portLabels[port.Label]; ok {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Port label %s already in use by %s", port.Label, other))View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped '%v' detail to see which task stanza failed
- Run `nomad job validate <file>` locally to catch the exact task error before submit
- Fix the offending field in the named task (driver, resources, services, template, artifact...)
- Ensure referenced port labels and group-level stanzas exist in the parent task group
- Compare against a known-good example for the driver/version you target
Example fix
// before
task "app" {
driver = "dockr"
resources {
cpu = -100
memory = 0
}
}
// after
task "app" {
driver = "docker"
resources {
cpu = 500
memory = 256
}
} Defensive patterns
Strategy: validation
Validate before calling
func validateTasks(j *api.Job) error {
var errs error
for _, tg := range j.TaskGroups {
for _, t := range tg.Tasks {
if t.Driver == "" { errs = multierror.Append(errs, fmt.Errorf("task %s: missing driver", t.Name)) }
if r := t.Resources; r != nil {
if r.CPU < 0 || r.MemoryMB < 0 { errs = multierror.Append(errs, fmt.Errorf("task %s: negative resources", t.Name)) }
}
// port label refs in services must exist in group network
labels := map[string]bool{}
for _, n := range tg.Networks { for _, p := range n.ReservedPorts { labels[p.Label] = true }; for _, p := range n.DynamicPorts { labels[p.Label] = true } }
for _, s := range t.Services { if s.PortLabel != "" && !labels[s.PortLabel] { errs = multierror.Append(errs, fmt.Errorf("task %s: unknown port label %q", t.Name, s.PortLabel)) } }
}
}
return errs
} Type guard
func taskValid(t *api.Task) bool {
return t.Name != "" && t.Driver != "" && t.Resources != nil &&
t.Resources.CPU >= 0 && t.Resources.MemoryMB >= 0
} Prevention
- Run `nomad job validate` on every spec before submit (CI gate)
- Use schema-aware tooling (Terraform nomad_job, Packer templates) rather than raw string templating
- Copy task stanzas from driver-specific official examples
- Check port label references match group network definitions after refactors
When it happens
Trigger: Registering a job where a task has: an unknown/unavailable driver name, invalid resource stanza (negative CPU/memory, memory above limits), invalid service/check definitions, bad artifact sources, invalid template stanza, invalid log config, or a task field not permitted for the given job type.
Common situations: Typo in driver name (e.g. "docker" misspelled); referencing task group network port labels that don't exist; memory oversubscription fields on older Nomad versions; copy-pasted task stanzas carrying fields from another driver; template/consul misconfigurations caught at submit time.
Related errors
- Task group %s validation failed: %v
- Job type %q does not allow update block
- Job type %q does not allow migrate block
- Task group scaling policy validation failed: %v
- Template %d validation failed: %s
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/4b02800e00cdc15d.
Report an issue: GitHub.