hashicorp/nomad · error

Service [%s]->%s or Check %s must specify task parameter

Error message

Service [%s]->%s or Check %s must specify task parameter

What it means

A task group service or its script check has no task defined. Script checks execute inside a task's filesystem/allocation, so Nomad must know which task to run the check in; task-level services inherit the parent task's name, but group-level services must set `task` explicitly when they contain a script check.

Source

Thrown at nomad/structs/structs.go:7595

	if providerSet.Size() > 1 {
		mErr.Errors = append(mErr.Errors,
			errors.New("Multiple service providers used: task group services must use the same provider"))
	}

	return mErr.ErrorOrNil()
}

// validateScriptChecksInGroupServices ensures group-level services with script
// checks know what task driver to use. Either the service.task or service.check.task
// parameter must be configured.
func (tg *TaskGroup) validateScriptChecksInGroupServices() error {
	var mErr multierror.Error
	for _, service := range tg.Services {
		if service.TaskName == "" {
			for _, check := range service.Checks {
				if check.Type == "script" && check.TaskName == "" {
					mErr.Errors = append(mErr.Errors,
						fmt.Errorf("Service [%s]->%s or Check %s must specify task parameter",
							tg.Name, service.Name, check.Name,
						))
				}
			}
		}
	}
	return mErr.ErrorOrNil()
}

// validateScalingPolicy ensures that the scaling policy has consistent
// min and max, not in conflict with the task group count
func (tg *TaskGroup) validateScalingPolicy(j *Job) error {
	if tg.Scaling == nil {
		return nil
	}

	var mErr multierror.Error

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set `task = "<taskname>"` on the group-level service block
  2. Or set `task` directly on the script check
  3. Or move the service back to task-level where the task is implicit

Example fix

// before
group "app" {
  service {
    name = "app"
    check { type = "script" command = "/bin/health" }
  }
}
// after
group "app" {
  service {
    name = "app"
    task = "server"
    check { type = "script" command = "/bin/health" }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

for _, svc := range group.Services {
  if svc.TaskName == "" {
    for _, c := range svc.Checks {
      if c.Type == "script" && c.TaskName == "" {
        return fmt.Errorf("script check %q needs a task", c.Name)
      }
    }
  }
}

Type guard

func scriptCheckHasTask(svc *api.Service) bool {
  if svc.TaskName != "" { return true }
  for _, c := range svc.Checks {
    if c.Type == "script" && c.TaskName == "" { return false }
  }
  return true
}

Prevention

When it happens

Trigger: Declaring a group-level `service` (which has no implicit task) whose `check` has `type = "script"` and no `task` field set in either the service or the check.

Common situations: Moving a service from task-level to group-level in Nomad 0.12+ and forgetting that the implicit task name is lost; adding a script check copied from a task-level example into a group-level service.

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