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
- Rename the duplicate group at the given index to a unique name
- De-duplicate group generation in your templating logic
- Run 'nomad job validate' in CI to catch duplicates before submit
- 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
- De-duplicate group names in templating loops (append suffix per iteration)
- Review merged job files for overlapping group blocks
- Add a duplicate-name check to your job spec linter
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
- Job task group %d missing name
- Task group %s validation failed: %v
- Group %q has warnings: %v
- Task %d redefines '%s' from task %d
- ErrConnectRequireOneNetwork
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/54c264b77541b156.
Report an issue: GitHub.