hashicorp/nomad · error

task driver does not support exec

Error message

task driver does not support exec

What it means

DriverHandle.ExecStreaming first checks whether the task driver implements drivers.ExecTaskStreamingRawDriver, then drivers.ExecTaskStreamingDriver. If the driver implements neither interface, it cannot stream exec sessions into the running task and returns this plain error.

Source

Thrown at client/allocrunner/taskrunner/driver_handle.go:97

}

// ExecStreaming is the handled used by client endpoint handler to invoke the appropriate task driver exec.
// while allowing to stream input and output
func (h *DriverHandle) ExecStreaming(ctx context.Context,
	command []string,
	tty bool,
	stream drivers.ExecTaskStream) error {
	if h == nil {
		return te.ErrTaskNotRunning
	}

	if impl, ok := h.driver.(drivers.ExecTaskStreamingRawDriver); ok {
		return impl.ExecTaskStreamingRaw(ctx, h.taskID, command, tty, stream)
	}

	d, ok := h.driver.(drivers.ExecTaskStreamingDriver)
	if !ok {
		return fmt.Errorf("task driver does not support exec")
	}

	execOpts, doneCh := drivers.StreamToExecOptions(
		ctx, command, tty, stream)

	result, err := d.ExecTaskStreaming(ctx, h.taskID, execOpts)
	if err != nil {
		return err
	}

	execOpts.Stdout.Close()
	execOpts.Stderr.Close()

	select {
	case err = <-doneCh:
	case <-ctx.Done():
		err = fmt.Errorf("exec task timed out: %v", ctx.Err())
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Use a driver that supports exec (e.g. exec, docker) for workloads you need to exec into
  2. Check driver capabilities via fingerprinting before offering exec in tooling
  3. For raw streaming needs, ensure the driver implements ExecTaskStreamingRawDriver
  4. Fall back to driver-specific debugging (logs) instead of exec
Defensive patterns

Strategy: type-guard

Validate before calling

// check driver capabilities before attempting exec
driverInfo, err := client.Nodes().Driver(nodeID, driverName, nil)
if err != nil || driverInfo == nil || !driverInfo.Detected {
    return fmt.Errorf("driver %s unavailable for exec", driverName)
}

Type guard

func supportsExec(d drivers.DriverPlugin) bool {
    _, basic := d.(drivers.ExecTaskStreamingDriver)
    _, raw := d.(drivers.ExecTaskStreamingRawDriver)
    return basic || raw
}

Try / catch

if err := handle.ExecStreaming(ctx, cmd, tty, stream); err != nil {
    if strings.Contains(err.Error(), "does not support exec") {
        return fmt.Errorf("driver %T has no exec support; use logs or a different driver", handle.driver)
    }
    return err
}

Prevention

When it happens

Trigger: Calling AllocExec / task exec streaming against a task whose driver only implements the basic drivers.TaskDriver interface (no exec streaming capability), e.g. exec'ing into a container with a driver that lacks exec support.

Common situations: Using 'nomad alloc exec' on a driver such as java, qemu, or a custom/3rd-party driver that does not implement ExecTaskStreaming; exec on a driver whose exec support was never implemented; calling the API programmatically against such a driver.

Related errors


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