hashicorp/nomad · error

Job task group %d missing name

Error message

Job task group %d missing name

What it means

Job.Validate() checks every task group has a non-empty Name, appending 'Job task group %d missing name' (1-based index) when tg.Name is empty. Group names are required keys for allocation tracking and the API.

Source

Thrown at nomad/structs/structs.go:4828

	const MaxDescriptionCharacters = 1000
	if j.UI != nil {
		if len(j.UI.Description) > MaxDescriptionCharacters {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("UI description must be under 1000 characters, currently %d", len(j.UI.Description)))
		}
	}

	if j.VersionTag != nil {
		if len(j.VersionTag.Description) > MaxDescriptionCharacters {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Tagged version description must be under 1000 characters, currently %d", len(j.VersionTag.Description)))
		}
	}

	// Check for duplicate task groups
	taskGroups := make(map[string]int)
	for idx, tg := range j.TaskGroups {
		if tg.Name == "" {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Job task group %d missing name", idx+1))
		} else if existing, ok := taskGroups[tg.Name]; ok {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("Job task group %d redefines '%s' from group %d", idx+1, tg.Name, existing+1))
		} else {
			taskGroups[tg.Name] = idx
		}

		if tg.ShutdownDelay != nil && *tg.ShutdownDelay < 0 {
			mErr.Errors = append(mErr.Errors, errors.New("ShutdownDelay must be a positive value"))
		}

		if j.Type == "system" && tg.Count > 1 {
			mErr.Errors = append(mErr.Errors,
				fmt.Errorf("Job task group %s has count %d. Count cannot exceed 1 with system scheduler",
					tg.Name, tg.Count))
		}
	}

	// Validate the task group

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add a name to the group block or set TaskGroups[i].Name in the JSON
  2. Ensure generated job specs always populate group names
  3. Run 'nomad job validate' on generated specs in CI
  4. If parsing HCL, verify the group label survived templating

Example fix

// before
group {
  count = 1
}
// after
group "web" {
  count = 1
}
Defensive patterns

Strategy: validation

Validate before calling

for i, tg := range job.TaskGroups {
    if tg.Name == "" {
        return fmt.Errorf("task group %d missing name", i+1)
    }
}
return nil

Type guard

func hasNamedGroups(j *structs.Job) bool {
    for _, tg := range j.TaskGroups {
        if tg == nil || tg.Name == "" {
            return false
        }
    }
    return len(j.TaskGroups) > 0
}

Try / catch

if err := job.Validate(); err != nil {
    if strings.Contains(err.Error(), "missing name") {
        return ErrGroupMissingName
    }
    return err
}

Prevention

When it happens

Trigger: Submitting a job JSON/HCL where a group block omits the name, e.g. JSON produced by a script that drops the Name field or an HCL group without a label.

Common situations: Programmatic job generation (SDK/API) where TaskGroups structs are built without setting Name, or malformed HCL where the group label was accidentally removed.

Related errors


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