hashicorp/nomad · error
could not find destination path relative to chroot: %w
Error message
could not find destination path relative to chroot: %w
What it means
The template renderer's sandbox function chroots into the alloc dir (sandboxPath) and then computes the template's destination path relative to that chroot using filepath.Rel. filepath.Rel returns an error when the two paths cannot be made relative to each other — typically because destPath is not under sandboxPath, or the paths use incompatible forms (e.g. one relative, one absolute, or differing volume roots). The renderer returns this error and the template render fails.
Source
Thrown at client/allocrunner/taskrunner/template/renderer/template_sandbox_default.go:32
// sandbox is the non-Windows sandbox implementation, which relies on chroot.
// Although chroot is not an appropriate boundary for tasks (implicitly
// untrusted), here the only code that's executing is Nomad itself. Returns the
// new destPath inside the chroot.
func sandbox(sandboxPath, destPath string) (string, error) {
err := syscall.Chroot(sandboxPath)
if err != nil {
// if the user is running in unsupported non-root configuration, we
// can't build the sandbox, but need to handle this gracefully
fmt.Fprintf(os.Stderr, "template-render sandbox %q not available: %v",
sandboxPath, err)
return destPath, nil
}
destPath, err = filepath.Rel(sandboxPath, destPath)
if err != nil {
return "", fmt.Errorf("could not find destination path relative to chroot: %w", err)
}
if !filepath.IsAbs(destPath) {
destPath = "/" + destPath
}
return destPath, nil
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Change the template's destination to a path inside the alloc dir (e.g. "local/foo.conf" or "NOMAD_SECRETS_DIR/...")
- Use a relative destination path in the template block instead of an absolute host path
- Check client template config (function_blacklist / disable_file_sandbox and sandbox settings) that affect sandboxPath
- Ensure the alloc dir path has no symlinks or irregular normalization that breaks filepath.Rel; align both paths' forms
- If writing outside the sandbox is truly required, evaluate whether sandboxing can be disabled for that client per security policy
Example fix
// before: template destination outside the alloc dir sandbox
template {
data = "..."
destination = "/etc/app/config.conf"
}
// after: destination inside the alloc dir
template {
data = "..."
destination = "local/config.conf"
} Defensive patterns
Strategy: validation
Validate before calling
// Validate template destinations before submitting the job
func validTemplateDest(dest string) bool {
if filepath.IsAbs(dest) {
return false // must be alloc-dir relative, e.g. "local/app.conf"
}
cleaned := filepath.Clean(dest)
return !strings.HasPrefix(cleaned, "..") && !filepath.IsAbs(cleaned)
}
// for each template block: if !validTemplateDest(t.Destination) { return err } Prevention
- Always use alloc-dir-relative destinations (local/, secrets/) in template blocks
- Run nomad job validate / plan before submitting jobs with template stanzas
- Avoid symlinks in alloc_dir that could break lexical path relativization
- Review client template sandbox settings when changing Nomad versions
When it happens
Trigger: In sandbox(), syscall.Chroot succeeded, but filepath.Rel(sandboxPath, destPath) fails because the template's destination path is not contained within the sandbox/alloc-dir path — e.g. a template block with a destination outside the alloc dir, or mismatched relative/absolute path forms.
Common situations: Job template blocks using absolute destination paths that escape the alloc dir (e.g. destination = "/etc/foo.conf" while sandboxing is enforced); misconfigured client template options changing the sandbox path; symlinked or normalized alloc dir paths where lexical Rel cannot succeed; comparing a relative destPath against an absolute sandboxPath.
Related errors
- failed to sandbox alloc dir %q: %w
- template source path escapes alloc directory
- template destination path escapes alloc directory
- Invalid change mode. Must be one of the following: noop, sig
- All templates should have same Once value
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0cff62039c267803.
Report an issue: GitHub.