hashicorp/nomad · error

Missing task resources

Error message

Missing task resources

What it means

Nomad's Task.Validate() collects all validation problems into a multierror. This error is appended when the Task struct has a nil Resources field. A task without a resources block cannot be scheduled because Nomad has no CPU/memory/network requirements to place it against, so validation fails before the job is accepted.

Source

Thrown at nomad/structs/structs.go:8272

		//
		// progress_deadline = 0 has a special meaning so it should not be
		// validated against the task's kill_timeout.
		conflictsWithProgressDeadline := jobType == JobTypeService &&
			tg.Update != nil &&
			tg.Update.ProgressDeadline > 0 &&
			t.KillTimeout > tg.Update.ProgressDeadline
		if conflictsWithProgressDeadline {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("KillTimout (%s) longer than the group's ProgressDeadline (%s)",
				t.KillTimeout, tg.Update.ProgressDeadline))
		}
	}
	if t.ShutdownDelay < 0 {
		mErr.Errors = append(mErr.Errors, errors.New("ShutdownDelay must be a positive value"))
	}

	// Validate the resources.
	if t.Resources == nil {
		mErr.Errors = append(mErr.Errors, errors.New("Missing task resources"))
	} else if err := t.Resources.Validate(); err != nil {
		mErr.Errors = append(mErr.Errors, err)
	}

	// Validate the log config
	if t.LogConfig == nil {
		mErr.Errors = append(mErr.Errors, errors.New("Missing Log Config"))
	} else if err := t.LogConfig.Validate(tg.EphemeralDisk); err != nil {
		mErr.Errors = append(mErr.Errors, err)
	}

	// Validate constraints and affinities.
	for idx, constr := range t.Constraints {
		if err := constr.Validate(); err != nil {
			outer := fmt.Errorf("Constraint %d validation failed: %s", idx+1, err)
			mErr.Errors = append(mErr.Errors, outer)
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add a resources stanza to the task with at least cpu and memory values.
  2. If constructing the Task in Go, set t.Resources = &nomadstructs.Resources{CPU: ..., MemoryMB: ...} before calling Validate.
  3. If the task is generated by tooling, fix the generator/template so the resources block is always emitted.
  4. Run `nomad job validate <file>` before submitting to catch this client-side.

Example fix

// before
task "app" {
  driver = "docker"
  config { image = "nginx" }
}
// after
task "app" {
  driver = "docker"
  config { image = "nginx" }
  resources {
    cpu    = 500
    memory = 256
  }
}
Defensive patterns

Strategy: validation

Validate before calling

func validateTaskResources(t *structs.Task) error {
	if t.Resources == nil {
		return fmt.Errorf("task %q: resources stanza is required", t.Name)
	}
	if t.Resources.CPU <= 0 || t.Resources.MemoryMB <= 0 {
		return fmt.Errorf("task %q: cpu and memory must be positive", t.Name)
	}
	return nil
}

Type guard

func hasResources(t *structs.Task) bool { return t != nil && t.Resources != nil }

Prevention

When it happens

Trigger: Submitting (job register/plan) a job whose task stanza omits the resources block (or building a Task struct in Go with Resources left nil, e.g. via taskspec/template expansion that didn't populate Resources).

Common situations: Hand-writing HCL jobs and forgetting the resources stanza inside a task; programmatic job construction that skips defaulting; older API clients that predate resources being effectively mandatory; custom tooling generating jobs from templates that drop empty blocks.

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/40f8c9706a18c3f3. Report an issue: GitHub.