hashicorp/nomad · error
destination escapes allocation directory
Error message
destination escapes allocation directory
What it means
DispatchPayloadConfig.Validate() rejects a `template` dispatch payload whose destination `File` resolves outside the allocation directory. It calls escapingfs.PathEscapesAllocViaRelative("task/local/", d.File), and if the path escapes (e.g. via `..` traversal or symlinks), validation fails. This guards the `task/local/` sandbox against path traversal.
Source
Thrown at nomad/structs/structs.go:6151
File string
}
func (d *DispatchPayloadConfig) Copy() *DispatchPayloadConfig {
if d == nil {
return nil
}
nd := new(DispatchPayloadConfig)
*nd = *d
return nd
}
func (d *DispatchPayloadConfig) Validate() error {
// Verify the destination doesn't escape
escaped, err := escapingfs.PathEscapesAllocViaRelative("task/local/", d.File)
if err != nil {
return fmt.Errorf("invalid destination path: %v", err)
} else if escaped {
return fmt.Errorf("destination escapes allocation directory")
}
return nil
}
const (
TaskLifecycleHookPrestart = "prestart"
TaskLifecycleHookPoststart = "poststart"
TaskLifecycleHookPoststop = "poststop"
)
type TaskLifecycleConfig struct {
Hook string
Sidecar bool
}
func (d *TaskLifecycleConfig) Copy() *TaskLifecycleConfig {
if d == nil {View on GitHub (pinned to 482b49bf1a)
Solutions
- Set the template `destination` to a relative path inside the alloc dir, e.g. `task/local/payload.txt` or `local/payload.txt`.
- Remove any `../` traversal segments from the destination path.
- If you need data in another location, copy it at runtime from task/local/ rather than pointing the destination there.
Example fix
// before
template {
data = "{{ payload }}"
destination = "../../shared/input.txt"
}
// after
template {
data = "{{ payload }}"
destination = "task/local/input.txt"
} Defensive patterns
Strategy: validation
Validate before calling
func validDispatchDestination(dest string) bool {
if filepath.IsAbs(dest) {
return false
}
escaped, err := escapingfs.PathEscapesAllocViaRelative("task/local/", dest)
return err == nil && !escaped
}
// call before building the job: validDispatchDestination(cfg.File) Prevention
- Always write template destinations as paths relative to the alloc dir rooted at task/local/.
- Never use `..` segments or absolute paths in template destinations.
- Run `nomad job validate` in CI before submitting dispatch-template jobs.
When it happens
Trigger: Submitting or validating a job whose `template` block uses `data` (dispatch payload) with a `destination` file path such as `../../etc/foo`, an absolute path, or any relative path that escapes `task/local/`.
Common situations: Typo of extra `../` segments in a template destination; copy-pasting paths from other tools assuming a different working directory; trying to write outside the alloc dir to share files between tasks; absolute paths (`/etc/...`) used by mistake.
Related errors
- Disconnect cannot be configured with both lost_after and sto
- lost_after cannot be a negative duration
- stop_after cannot be a negative duration
- Missing job ID
- Job ID contains a space
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/12c93d6464f3e952.
Report an issue: GitHub.