hashicorp/nomad · error

failed to inspect exit code of exec object: %w

Error message

failed to inspect exit code of exec object: %w

What it means

Once the exec's output has been copied, the driver inspects the exec instance to read its exit code via ExecInspect. If that inspection call fails, the command's output is returned but the exit status is unknown and this wrapped error is reported.

Source

Thrown at drivers/docker/handle.go:121

	startOpts := mclient.ExecAttachOptions{TTY: false}

	// hijack exec output streams
	hijacked, err := h.dockerClient.ExecAttach(ctx, exec.ID, startOpts)
	if err != nil {
		return nil, fmt.Errorf("failed to attach to exec object: %w", err)
	}

	_, err = stdcopy.StdCopy(stdout, stderr, hijacked.Reader)
	if err != nil {
		return nil, err
	}
	defer hijacked.Close()

	execResult.Stdout = stdout.Bytes()
	execResult.Stderr = stderr.Bytes()
	res, err := h.dockerClient.ExecInspect(ctx, exec.ID, mclient.ExecInspectOptions{})
	if err != nil {
		return execResult, fmt.Errorf("failed to inspect exit code of exec object: %w", err)
	}

	execResult.ExitResult.ExitCode = res.ExitCode
	return execResult, nil
}

func (h *taskHandle) Signal(ctx context.Context, s string) error {
	_, err := signals.Parse(s)
	if err != nil {
		return fmt.Errorf("failed to parse signal: %v", err)
	}

	_, err = h.dockerClient.ContainerKill(ctx, h.containerID, mclient.ContainerKillOptions{Signal: s})
	return err
}

// parseSignal interprets the signal name into an os.Signal. If no name is
// provided, the docker driver defaults to SIGTERM. If the OS is Windows and

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check the captured stdout/stderr in execResult for the actual command output — the command may have run fine; only the exit code is missing.
  2. Re-run the command; a fresh exec will have an inspectable exit code.
  3. Check Docker daemon availability and logs if errors are persistent.
  4. Upgrade the docker driver/engine if execs are being pruned before inspection (known garbage-collection races in older engines).

Example fix

// before: assuming failure means command failed
res, err := client.ExecInspect(...)
// after: treat as unknown exit code, output still valid
if err != nil {
    // inspect execResult.Stdout/Stderr from the returned execResult before retrying
}
Defensive patterns

Strategy: fallback

Try / catch

res, err := driver.ExecTask(ctx, taskID, opts)
if err != nil && strings.Contains(err.Error(), "failed to inspect exit code of exec object") {
    // execResult may still carry stdout/stderr; use them before deciding to rerun
    if res != nil && len(res.Stdout) > 0 {
        log.Printf("output captured despite exit-code loss: %s", res.Stdout)
    }
}

Prevention

When it happens

Trigger: h.dockerClient.ExecInspect(ctx, exec.ID, ...) errors: exec record already pruned by the engine (execs are removed shortly after completion), daemon unreachable, or the container/exec was removed concurrently.

Common situations: Long-running exec finishing while the Docker daemon is restarted; Docker versions where completed execs are garbage-collected quickly; querying exit code of an exec whose container was removed by an auto-remove/stop race.

Related errors


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