hashicorp/nomad · error
Must specify a source path or have an embedded template
Error message
Must specify a source path or have an embedded template
What it means
Template.Validate() requires that a template stanza has renderable content: either a `source` path (SourcePath) or inline `data`/`embedded template` (EmbeddedTmpl). If both are empty there is nothing to render, so validation fails and the error is appended to the template's multierror.
Source
Thrown at nomad/structs/structs.go:8964
nt.ChangeScript = t.ChangeScript.Copy()
nt.Wait = t.Wait.Copy()
return nt
}
func (t *Template) Canonicalize() {
if t.ChangeSignal != "" {
t.ChangeSignal = strings.ToUpper(t.ChangeSignal)
}
}
func (t *Template) Validate() error {
var mErr multierror.Error
// Verify we have something to render
if t.SourcePath == "" && t.EmbeddedTmpl == "" {
_ = multierror.Append(&mErr, fmt.Errorf("Must specify a source path or have an embedded template"))
}
// Verify we can render somewhere
if t.DestPath == "" {
_ = multierror.Append(&mErr, fmt.Errorf("Must specify a destination for the template"))
}
// Verify the destination doesn't escape
escaped, err := escapingfs.PathEscapesAllocViaRelative("task", t.DestPath)
if err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("invalid destination path: %v", err))
} else if escaped {
mErr.Errors = append(mErr.Errors, fmt.Errorf("destination escapes allocation directory"))
}
// Verify a proper change mode
switch t.ChangeMode {
case TemplateChangeModeNoop, TemplateChangeModeRestart:View on GitHub (pinned to 482b49bf1a)
Solutions
- Add inline content via the `data` field: template { data = "..." destination = "..." }.
- Or point to a file: template { source = "tpl/nginx.conf.tpl" destination = "..." }.
- Check HCL indentation/nesting so the template stanza actually captures source/data.
Example fix
// before
template {
destination = "local/config.yml"
}
// after
template {
data = "key: value"
destination = "local/config.yml"
} Defensive patterns
Strategy: validation
Validate before calling
// Pre-submit check
if tpl.Source == "" && tpl.Data == "" {
return errors.New("template needs source or data")
} Prevention
- Always pair a template destination with source or data.
- Check HCL nesting so fields land in the right stanza.
- Run `nomad job validate` before every apply.
When it happens
Trigger: Submitting a job with an empty `template {}` stanza — no `source`, no `data`, no `destination`. Thrown whenever t.SourcePath == "" && t.EmbeddedTmpl == "" during job validation.
Common situations: HCL templating accident where `source`/`data` were dropped or indented into a nested block; generating job specs programmatically and leaving the template fields blank; converting from another orchestrator format and forgetting the content field.
Related errors
- Must specify a destination for the template
- Must specify signal value when change mode is signal
- template source path escapes alloc directory
- template destination path escapes alloc directory
- Invalid change mode. Must be one of the following: noop, sig
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/e2c6ed0e3fd99c6c.
Report an issue: GitHub.