hashicorp/nomad · error

Job task group %d redefines '%s' from group %d

Error message

Job task group %d redefines '%s' from group %d

What it means

Job.Validate() enforces unique task group names: if tg.Name was already seen in an earlier group, it appends 'Job task group %d redefines %s from group %d' with 1-based indices. Duplicate group names would make allocations and job state ambiguous.

Source

Thrown at nomad/structs/structs.go:4830

	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
	for _, tg := range j.TaskGroups {
		if err := tg.Validate(j); err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Rename the duplicate group at the given index to a unique name
  2. De-duplicate group generation in your templating logic
  3. Run 'nomad job validate' in CI to catch duplicates before submit
  4. Use the reported indices (current group and original group) to locate the clash

Example fix

// before
group "web" {}
group "web" {}
// after
group "web" {}
group "web-admin" {}
Defensive patterns

Strategy: validation

Validate before calling

seen := map[string]bool{}
for _, tg := range job.TaskGroups {
    if seen[tg.Name] {
        return fmt.Errorf("duplicate task group name %q", tg.Name)
    }
    seen[tg.Name] = true
}
return nil

Type guard

func uniqueGroupNames(j *structs.Job) bool {
    seen := make(map[string]struct{}, len(j.TaskGroups))
    for _, tg := range j.TaskGroups {
        if _, ok := seen[tg.Name]; ok {
            return false
        }
        seen[tg.Name] = struct{}{}
    }
    return true
}

Try / catch

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

Prevention

When it happens

Trigger: Submitting a job where two or more group blocks share the same name, e.g. duplicated group blocks from templating or merged job files.

Common situations: YAML/HCL template loops rendering the same group name twice, concatenating job fragments, copy-pasting a group block and forgetting to rename it.

Related errors


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