hashicorp/nomad · error

Check %q invalid: cannot use address_mode="driver", only che

Error message

Check %q invalid: cannot use address_mode="driver", only checks defined in a "task" service block can use this mode

What it means

A check declared task_name (i.e. a task-level check) and also set address_mode="driver"; driver address mode is only allowed for checks defined within a task's service block, so this combination in a group-level service's checks is rejected. (The message uses the service's name, not the check's.)

Source

Thrown at nomad/structs/structs.go:7545

		// Track that we have seen this service provider
		providerSet.Insert(service.Provider)

		if err := service.Validate(); err != nil {
			outer := fmt.Errorf("Service[%d] %s validation failed: %s", i, service.Name, err)
			mErr.Errors = append(mErr.Errors, outer)
			// we break here to avoid the risk of crashing on null-pointer
			// access in a later step, accepting that we might miss out on
			// error messages to provide the user.
			continue
		}
		if service.AddressMode == AddressModeDriver {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("service %q cannot use address_mode=\"driver\", only services defined in a \"task\" block can use this mode", service.Name))
		}

		for _, check := range service.Checks {
			if check.TaskName != "" {
				if check.AddressMode == AddressModeDriver {
					mErr.Errors = append(mErr.Errors, fmt.Errorf("Check %q invalid: cannot use address_mode=\"driver\", only checks defined in a \"task\" service block can use this mode", service.Name))
				}
				if !taskSet.Contains(check.TaskName) {
					mErr.Errors = append(mErr.Errors,
						fmt.Errorf("Check %s invalid: refers to non-existent task %s", check.Name, check.TaskName))
				}
			}
		}
	}

	// Produce an error of any services which are not unique enough in the group
	// i.e. have same <task, name, port>
	if idDuplicateSet.Size() > 0 {
		mErr.Errors = append(mErr.Errors,
			fmt.Errorf(
				"Services are not unique: %s",
				idDuplicateSet.StringFunc(
					func(u unique) string {
						s := u.task + "->" + u.name

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Remove address_mode="driver" from the check (use host/auto).
  2. Move the service and check into the task block where driver mode is permitted.
  3. Drop the task field from the check if group-level host addressing is intended.

Example fix

// before
check "health" { address_mode="driver" task="web" }
// after
check "health" { address_mode="host" }
Defensive patterns

Strategy: validation

Validate before calling

for _, c := range svc.Checks {
  if c.TaskName != "" && c.AddressMode == "driver" {
    return fmt.Errorf("check %q: driver address_mode only valid in task services", c.Name)
  }
}

Prevention

When it happens

Trigger: A group-level service with a check that sets task = "..." and address_mode = "driver"; validation iterates service.Checks and flags check.AddressMode == AddressModeDriver when check.TaskName != "".

Common situations: Copy-pasting checks from task services to group services; enabling driver address mode for Consul checks defined at group level; refactoring services between scopes.

Related errors


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