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

  1. 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).
  2. Add the desired emulator to allowed_emulators in the Nomad client config and restart the client.
  3. 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

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/99f6dc0237a71396. Report an issue: GitHub.