hashicorp/nomad · error
volumes are not enabled; cannot mount host path: %q
Error message
volumes are not enabled; cannot mount host path: %q
What it means
When host volume mounts are disabled (d.config.Volumes.Enabled is false), containerBinds still allows relative/task-dir sources but checks with escapingfs.ChildEscapesParentDir that the source stays inside the allocation directory. This error means the requested bind's source escapes the alloc dir while host-path mounting is forbidden — a security guard against host filesystem access.
Source
Thrown at drivers/docker/driver.go:812
return nil, fmt.Errorf("invalid docker volume %q: %v", userbind, err)
}
// Paths inside task dir are always allowed when using the default driver,
// Relative paths are always allowed as they mount within a container
// When a VolumeDriver is set, we assume we receive a binding in the format
// volume-name:container-dest
// Otherwise, we assume we receive a relative path binding in the format
// relative/to/task:/also/in/container
if taskLocalBindVolume {
src = expandPath(task.TaskDir().Dir, src)
} else {
// Resolve dotted path segments
src = filepath.Clean(src)
}
if !d.config.Volumes.Enabled {
if err := escapingfs.ChildEscapesParentDir(task.AllocDir, src); err != nil {
return nil, fmt.Errorf("volumes are not enabled; cannot mount host path: %q", userbind)
}
}
bind := src + ":" + dst
opts := mode
if opts != "" {
if selinuxLabel != "" {
opts += "," + selinuxLabel
}
} else {
opts = selinuxLabel
}
if opts != "" {
bind += ":" + opts
}
binds = append(binds, bind)
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Remove the host-path bind from config.volumes, or restrict it to paths within the alloc dir.
- Enable volumes on the client if host-path mounts are genuinely required (with operator approval).
- Use Nomad host volumes declared in client config and referenced via the volume stanza, which are ACL-controlled.
- Fix relative paths that use '..' to escape the allocation directory.
Example fix
// before
config { volumes = ["/etc/passwd:/tmp/passwd:ro"] }
// after
config { volumes = ["local/data:/data:ro"] } Defensive patterns
Strategy: validation
Validate before calling
func escapesAllocDir(allocDir, src string) bool {
clean := filepath.Clean(src)
return !strings.HasPrefix(clean, filepath.Clean(allocDir)+string(os.PathSeparator)) && !filepath.IsAbs(clean) == false && strings.HasPrefix(clean, "..")
} Prevention
- Use paths inside the alloc dir (local/, alloc/) when volumes are disabled
- Never reference absolute host paths in jobs targeting hardened clients
- Avoid '..' segments in relative volume sources
- Request host volume access via Nomad host volumes, not raw binds
When it happens
Trigger: config.volumes entry whose cleaned source path resolves outside task.AllocDir (e.g. "/etc", "../../hostpath", or an absolute host path) while the client has volumes.enabled = false. Raised in createContainerConfig.
Common situations: Jobs copied from dev clusters where volumes were enabled; attempts to mount host paths like /var/run/docker.sock without enabling volumes; relative paths with too many '..' segments escaping the alloc dir.
Related errors
- running container as ContainerAdmin is unsafe; change the co
- volumes are not enabled; cannot use volume driver %q
- invalid docker volume %q: %v
- invalid security_opt: %q
- opening seccomp profile (%s) failed: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/ffda1f7635ce3714.
Report an issue: GitHub.