hashicorp/nomad · error
Template %d has same destination as %d
Error message
Template %d has same destination as %d
What it means
Task.Validate detects two template blocks in the same task whose destination paths collide and reports "Template %d has same destination as %d" (1-based indices). Two templates rendering to the same file would nondeterministically overwrite each other, so it is rejected at job validation time.
Source
Thrown at nomad/structs/structs.go:8340
}
// Validate Vault.
if t.Vault != nil {
if err := t.Vault.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Vault validation failed: %v", err))
}
}
// Validate templates.
destinations := make(map[string]int, len(t.Templates))
for idx, tmpl := range t.Templates {
if err := tmpl.Validate(); err != nil {
outer := fmt.Errorf("Template %d validation failed: %s", idx+1, err)
mErr.Errors = append(mErr.Errors, outer)
}
if other, ok := destinations[tmpl.DestPath]; ok {
outer := fmt.Errorf("Template %d has same destination as %d", idx+1, other)
mErr.Errors = append(mErr.Errors, outer)
} else {
destinations[tmpl.DestPath] = idx + 1
}
}
// Validate actions.
actions := make(map[string]bool)
for _, action := range t.Actions {
if err := action.Validate(); err != nil {
outer := fmt.Errorf("Action %s validation failed: %s", action.Name, err)
mErr.Errors = append(mErr.Errors, outer)
}
if handled, seen := actions[action.Name]; seen && !handled {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Action %s defined multiple times", action.Name))
actions[action.Name] = true
continueView on GitHub (pinned to 482b49bf1a)
Solutions
- Give each template a unique destination path (e.g. local/a.conf vs local/b.conf)
- If one file needs content from multiple sources, merge into a single template block
- Run `nomad job validate` to enumerate all duplicate destinations before submit
Example fix
// before
template {
data = "A=1"
destination = "local/env.txt"
}
template {
data = "B=2"
destination = "local/env.txt"
}
// after
template {
data = "A=1"
destination = "local/a.env"
}
template {
data = "B=2"
destination = "local/b.env"
} Defensive patterns
Strategy: validation
Validate before calling
seen := map[string]int{}
for i, tmpl := range task.Templates {
if j, ok := seen[tmpl.DestPath]; ok {
return fmt.Errorf("templates %d and %d share destination %q", j, i+1, tmpl.DestPath)
}
seen[tmpl.DestPath] = i + 1
} Try / catch
if err := job.Validate(); err != nil {
if strings.Contains(err.Error(), "has same destination") { /* dedupe templates */ }
} Prevention
- Generate destinations from unique names, never copy-paste literals
- Lint job files for duplicate destination strings
- Keep one template per config file
When it happens
Trigger: A task defines two or more template stanzas with the identical `destination` path (including the same relative path via `local/`).
Common situations: Copy-pasting a template stanza and forgetting to change destination; rendering similar configs to the same file; generated HCL where destinations are parameterized and collide.
Related errors
- Template %d validation failed: %s
- Action %s defined multiple times
- template source path escapes alloc directory
- template destination path escapes alloc directory
- ErrConnectRequireOneNetwork
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/d5087770eb520523.
Report an issue: GitHub.