hashicorp/nomad · error
'%s' is not an allowed emulator
Error message
'%s' is not an allowed emulator
What it means
validateEmulator checks that the QEMU emulator binary requested via the driver's 'emulator' config (e.g. qemu-system-x86_64) is present in the operator-configured allowed_emulators list. Nomad throws this when a task requests an emulator the server admin has not allowlisted, because running arbitrary emulators would let a task execute unapproved binaries as the Nomad agent user.
Source
Thrown at drivers/qemu/driver.go:430
return true
}
}
return false
}
// hardcoded list of drive interfaces, Qemu currently supports
var allowedDriveInterfaces = []string{"ide", "scsi", "sd", "mtd", "floppy", "pflash", "virtio", "none"}
func isAllowedDriveInterface(driveInterface string) bool {
return slices.Contains(allowedDriveInterfaces, driveInterface)
}
// validateEmulator validate whether the specified emulator is in allowedEmulators
func validateEmulator(emulator string, allowedEmulators []string) error {
if len(allowedEmulators) > 0 {
if !slices.Contains(allowedEmulators, emulator) {
return fmt.Errorf("'%s' is not an allowed emulator", emulator)
}
}
return nil
}
// validateArgs ensures that all QEMU command line params are in the
// allowlist. This function must be called after all interpolation has
// taken place.
func validateArgs(pluginConfigAllowList, args []string) error {
if len(pluginConfigAllowList) > 0 {
allowed := map[string]struct{}{}
for _, arg := range pluginConfigAllowList {
allowed[arg] = struct{}{}
}
for _, arg := range args {
if strings.HasPrefix(strings.TrimSpace(arg), "-") {
if _, ok := allowed[arg]; !ok {
return fmt.Errorf("%q is not in args_allowlist", arg)View on GitHub (pinned to 482b49bf1a)
Solutions
- Update the job's qemu driver 'emulator' option to match one of the values in the client's allowed_emulators list (check with 'nomad node status <node> -verbose' or the client.hcl).
- Add the desired emulator to allowed_emulators in the Nomad client config and restart the client.
- If no restriction is desired, remove allowed_emulators from the client config entirely — validation is skipped when the list is empty.
Example fix
// job (before)
config { emulator = "qemu-system-aarch64" image_path = "..." }
// after (matching client allowlist)
config { emulator = "qemu-system-x86_64" image_path = "..." } Defensive patterns
Strategy: validation
Validate before calling
const allowed := []string{"qemu-system-x86_64"} // mirror client's allowed_emulators
if slices.Contains(allowed, cfg.Emulator) == false {
return fmt.Errorf("emulator %q must be one of %v", cfg.Emulator, allowed)
} Type guard
func isAllowedEmulator(e string, allowed []string) bool {
return len(allowed) == 0 || slices.Contains(allowed, e)
} Try / catch
_, _, err := d.StartTask(cfg)
if err != nil && strings.Contains(err.Error(), "is not an allowed emulator") {
// fix job emulator option or ask operator to widen allowed_emulators
} Prevention
- Keep job emulator values in sync with the client's allowed_emulators list
- Run 'nomad job validate' before submitting jobs
- Document the allowlist for job authors
- Use templating/shared vars to source the emulator name from one place
When it happens
Trigger: Calling StartTask (or the internal paths via findEmulators) where the task's driver config sets 'emulator' to a value not contained in the client's allowed_emulators list; note validation only runs when allowed_emulators is non-empty.
Common situations: Client config sets allowed_emulators = ["qemu-system-x86_64"] but the job specifies qemu-system-i386 or qemu-system-aarch64; operator tightened the allowlist after jobs were written; typo in the emulator name in the job file.
Related errors
- QEMU graceful shutdown is unsupported on the Windows platfor
- %q is not in args_allowlist
- taskConfig with ID '%s' already started
- failed to decode driver config: %v
- image_path must be set
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/99f6dc0237a71396.
Report an issue: GitHub.