hashicorp/nomad · error
image_path is not in the allowed paths
Error message
image_path is not in the allowed paths
What it means
The QEMU driver validates, at task start, that the VM image path (image_path) is either inside one of the client's configured 'image_paths' allowlist directories or inside the task's allocation directory. If isAllowedImagePath() rejects the path, StartTask refuses to launch the VM. This is a security guard against arbitrary file access by task authors, since QEMU would otherwise run with whatever disk image the task specifies.
Source
Thrown at drivers/qemu/driver.go:489
handle.Config = cfg
if err := validateEmulator(driverConfig.Emulator, d.config.EmulatorsAllowList); err != nil {
return nil, nil, err
}
if err := validateArgs(d.config.ArgsAllowList, driverConfig.Args); err != nil {
return nil, nil, err
}
// Get the image source
vmPath := driverConfig.ImagePath
if vmPath == "" {
return nil, nil, fmt.Errorf("image_path must be set")
}
vmID := filepath.Base(vmPath)
if !isAllowedImagePath(d.config.ImagePaths, cfg.AllocDir, vmPath) {
return nil, nil, fmt.Errorf("image_path is not in the allowed paths")
}
// Parse configuration arguments
// Create the base arguments
emulator := "x86_64"
if driverConfig.Emulator != "" {
// COMPAT: TrimPrefix to support full emulator name
// which was required in 1.11.1.
emulator = strings.TrimPrefix(driverConfig.Emulator, "qemu-system-")
}
accelerator := "tcg"
if driverConfig.Accelerator != "" {
accelerator = driverConfig.Accelerator
}
machineType := "pc"
if driverConfig.MachineType != "" {
machineType = driverConfig.MachineTypeView on GitHub (pinned to 482b49bf1a)
Solutions
- Add the directory containing the VM image to the client QEMU driver config: plugin "qemu" { driver "qemu" { image_paths = ["/srv/images"] } } and restart the Nomad client.
- Place the image inside the task's allocation directory (e.g. download it with an artifact block) which is always allowed.
- Verify the image_path in the task's driver config exactly matches a real file under one of the allowed roots (check for typos and symlinks).
Example fix
// task config: before
image_path = "/home/ops/alpine.qcow2"
// after (client hcl: plugin "qemu" { config { image_paths = ["/srv/images"] } })
image_path = "/srv/images/alpine.qcow2" Defensive patterns
Strategy: validation
Validate before calling
// before submitting, confirm image lives under an allowed root
const allowedRoots = ["/srv/images"]; // must match client config image_paths
function isAllowedImagePath(root, allocDir, p) {
const abs = require("path").resolve(p);
return [allocDir, ...root].some
? [allocDir, ...allowedRoots].some((r) => abs.startsWith(require("path").resolve(r) + require("path").sep))
: false;
} Type guard
function hasAllowedImagePath(cfg) {
return typeof cfg.image_path === "string" && cfg.image_path.length > 0 &&
allowedRoots.some((r) => require("path").resolve(cfg.image_path).startsWith(require("path").resolve(r) + require("path").sep));
} Try / catch
try {
await nomad.jobs.startTask(cfg);
} catch (e) {
if (String(e.message).includes("image_path is not in the allowed paths")) {
console.error(`Move ${cfg.image_path} under an image_paths root or add its dir to client config`);
}
throw e;
} Prevention
- Keep VM images in a single dedicated directory and register it in client image_paths.
- Prefer artifact blocks so images land in the alloc dir (always allowed).
- Avoid symlinks for images; resolve paths before comparing against allowlist.
- After changing client config image_paths, restart the Nomad client agent.
When it happens
Trigger: Calling tasks.start (QEMU driver) with driver config image_path pointing to a file outside config.image_paths allowlist and outside the task's alloc dir; empty or mis-scoped image_paths in the client 'plugin.qemu.driver.image_paths' config; using a relative or symlinked path that resolves outside allowed roots.
Common situations: Operator forgets to add the image directory to image_paths in the Nomad client config; dev setups using images in /home or /tmp while allowlist points elsewhere; images mounted at a different path on the client node than in the allowlist; path typo or symlink chain escaping the allowlist.
Related errors
- %q is not in args_allowlist
- running container as ContainerAdmin is unsafe; change the co
- QEMU graceful shutdown is unsupported on the Windows platfor
- ACL token not found
- running as user %q is disallowed
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0659df482d117b7e.
Report an issue: GitHub.