hashicorp/nomad · error
volumes are not enabled; cannot use volume driver %q
Error message
volumes are not enabled; cannot use volume driver %q
What it means
containerBinds rejects volume usage when host volumes are globally disabled on the docker driver (client option volumes.enabled = false) but the task specifies a non-empty volume_driver. Bind mounts of the alloc/task/secret dirs are always allowed, but any explicit volume driver implies a host/volume-driver mount that requires volumes to be enabled. This is a client-level security policy guard.
Source
Thrown at drivers/docker/driver.go:768
if err != nil {
return fmt.Errorf("the image does not exist: %v", err)
}
// LCOW If we are running a Linux Container on Windows, we need to mount it correctly, as c:\ does not exist on unix
if imageConfig.Os == "linux" {
a := []rune(task.Env[taskenv.AllocDir])
task.Env[taskenv.AllocDir] = strings.ReplaceAll(string(a[2:]), "\\", "/")
l := []rune(task.Env[taskenv.TaskLocalDir])
task.Env[taskenv.TaskLocalDir] = strings.ReplaceAll(string(l[2:]), "\\", "/")
s := []rune(task.Env[taskenv.SecretsDir])
task.Env[taskenv.SecretsDir] = strings.ReplaceAll(string(s[2:]), "\\", "/")
}
return nil
}
func (d *Driver) containerBinds(task *drivers.TaskConfig, driverConfig *TaskConfig) ([]string, error) {
taskLocalBindVolume := driverConfig.VolumeDriver == ""
if !d.config.Volumes.Enabled && !taskLocalBindVolume {
return nil, fmt.Errorf("volumes are not enabled; cannot use volume driver %q", driverConfig.VolumeDriver)
}
allocDirBind := fmt.Sprintf("%s:%s", task.TaskDir().SharedAllocDir, task.Env[taskenv.AllocDir])
taskLocalBind := fmt.Sprintf("%s:%s", task.TaskDir().LocalDir, task.Env[taskenv.TaskLocalDir])
secretDirBind := fmt.Sprintf("%s:%s", task.TaskDir().SecretsDir, task.Env[taskenv.SecretsDir])
selinuxLabel := d.config.Volumes.SelinuxLabel
binds := []string{allocDirBind, taskLocalBind, secretDirBind}
logsROFlag := "ro"
if selinuxLabel != "" {
// Apply SELinux Label to each built-in bind
for i := range binds {
binds[i] = fmt.Sprintf("%s:%s", binds[i], selinuxLabel)
}
logsROFlag = "ro," + selinuxLabel
}
allocLogsDirBind := fmt.Sprintf("%s/logs:%s/logs:%s", task.TaskDir().SharedAllocDir, task.Env[taskenv.AllocDir], logsROFlag)View on GitHub (pinned to 482b49bf1a)
Solutions
- Enable volumes on the client: set plugin 'docker' config volumes { enabled = true } in the client hcl and restart.
- Remove the volume_driver field if only default alloc-dir bind mounts are needed.
- Switch to Nomad host volumes / CSI volumes, which have their own ACL-gated access model.
- If only bind mounts are intended, omit volume_driver so taskLocalBindVolume is true.
Example fix
// before (client config)
plugin "docker" { config { volumes { enabled = false } } }
// after
plugin "docker" { config { volumes { enabled = true } } } Defensive patterns
Strategy: validation
Validate before calling
// job-side guard before using volume_driver
if cfg.VolumeDriver != "" && !clientVolumesEnabled {
return fmt.Errorf("job requires volume_driver %q but client volumes are disabled", cfg.VolumeDriver)
} Prevention
- Keep client volume policy and job requirements documented together
- Prefer Nomad host volumes/CSI over docker volume_driver
- Omit volume_driver when only alloc-dir bind mounts are needed
- Run `nomad job validate` against a client with the same policy
When it happens
Trigger: Task sets config.volume_driver (e.g. "local", "cloudstor:azure", or a named host volume driver) while the Nomad client docker plugin config has volumes.enabled = false. Raised in createContainerConfig before container creation.
Common situations: Jobs migrated from clusters with volumes enabled to locked-down clients; setting volume_driver = "local" for docker named volumes on a security-hardened client; forgetting to enable volumes in the client's plugin configuration.
Related errors
- invalid docker volume %q: %v
- volumes are not enabled; cannot mount host path: %q
- volumes are not enabled; cannot mount volume: %q
- not <src>:<destination> format
- invalid volume specification: '%s'
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0d1bb10c4e0f04e6.
Report an issue: GitHub.