hashicorp/nomad · error

Task Group %v should have an ephemeral disk object

Error message

Task Group %v should have an ephemeral disk object

What it means

Nomad requires each task group to have an EphemeralDisk object; when `tg.EphemeralDisk == nil` during validation, this error naming the group is appended. Like the reschedule check, it typically indicates a hand-constructed job struct that never went through canonicalization, which normally populates a default ephemeral disk (migrate = true, sizeMB = 300).

Source

Thrown at nomad/structs/structs.go:7219

		if tg.ReschedulePolicy != nil {
			mErr = multierror.Append(mErr, fmt.Errorf("System or sysbatch jobs should not have a reschedule policy"))
		}
	} else {
		if tg.ReschedulePolicy != nil {
			if err := tg.ReschedulePolicy.Validate(); err != nil {
				mErr = multierror.Append(mErr, err)
			}
		} else {
			mErr = multierror.Append(mErr, fmt.Errorf("Task Group %v should have a reschedule policy", tg.Name))
		}
	}

	if tg.EphemeralDisk != nil {
		if err := tg.EphemeralDisk.Validate(); err != nil {
			mErr = multierror.Append(mErr, err)
		}
	} else {
		mErr = multierror.Append(mErr, fmt.Errorf("Task Group %v should have an ephemeral disk object", tg.Name))
	}

	// Validate the update strategy
	if u := tg.Update; u != nil {
		switch j.Type {
		case JobTypeService, JobTypeSystem:
		default:
			mErr = multierror.Append(mErr, fmt.Errorf("Job type %q does not allow update block", j.Type))
		}
		if err := u.Validate(); err != nil {
			mErr = multierror.Append(mErr, err)
		}
	}

	// Validate the migration strategy
	switch j.Type {
	case JobTypeService:
		if tg.Migrate != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add an `ephemeral_disk` stanza (even empty) to the task group.
  2. Call `job.Canonicalize()` before validating/submitting when building jobs via the Go API.
  3. Submit through the standard HTTP API/CLI so server-side canonicalization supplies defaults.

Example fix

// before
group "app" {
  task "app" {}
}
// after
group "app" {
  ephemeral_disk {
    migrate = true
    size_mb = 300
  }
  task "app" {}
}
Defensive patterns

Strategy: validation

Validate before calling

func ensureEphemeralDisk(j *api.Job) {
	for _, tg := range j.TaskGroups {
		if tg.EphemeralDisk == nil {
			tg.EphemeralDisk = &api.EphemeralDisk{
				Sticky:  pointer.Of(false),
				Migrate: pointer.Of(true),
				SizeMB:  pointer.Of(300),
			}
		}
	}
}

Type guard

func hasEphemeralDisk(tg *api.TaskGroup) bool { return tg != nil && tg.EphemeralDisk != nil }

Prevention

When it happens

Trigger: Submitting a job whose task group lacks an `ephemeral_disk` stanza and whose struct was not canonicalized — e.g. constructing `structs.TaskGroup` directly in Go tests or sending raw JSON without defaults.

Common situations: Go API users building TaskGroup structs manually and calling Validate without Canonicalize; minimal test fixtures; migration of very old job specs predating the ephemeral disk stanza.

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/14ae893be396f28d. Report an issue: GitHub.