Billionmail/BillionMail · critical

failed to start temporary container: %w

Error message

failed to start temporary container: %w

What it means

After successfully creating the temporary container, ExecHostCommand calls client.ContainerStart to run it; any failure there is wrapped as this error. The container exists at this point (and is cleaned up via the deferred cleanupContainer), but could not be started. Start failures are typically runtime/environment level rather than API-structure level.

Source

Thrown at core/internal/service/dockerapi/dockerapi.go:327

	// Create temporary container
	resp, err := d.client.ContainerCreate(
		ctx,
		config,
		hostConfig,
		nil,
		nil,
		"",
	)
	if err != nil {
		return nil, fmt.Errorf("failed to create temporary container: %w", err)
	}
	containerID := resp.ID
	defer d.cleanupContainer(ctx, containerID) // Ensure container is cleaned up

	// Start container
	if err := d.client.ContainerStart(ctx, containerID, container.StartOptions{}); err != nil {
		return nil, fmt.Errorf("failed to start temporary container: %w", err)
	}

	// Wait for container execution to complete
	statusCh, errCh := d.client.ContainerWait(ctx, containerID, container.WaitConditionNotRunning)
	select {
	case err := <-errCh:
		if err != nil {
			return nil, fmt.Errorf("failed waiting for container execution: %w", err)
		}
	case status := <-statusCh:
		result.ExitCode = int(status.StatusCode)
	}

	// Get container logs
	options := container.LogsOptions{
		ShowStdout: true,
		ShowStderr: true,
	}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Inspect the wrapped error and containerd/runc logs (journalctl -u docker) for the runtime failure reason
  2. Verify the command array's first element is an executable present in alpine:latest (use /bin/sh, not bash)
  3. Test manually: docker run --rm --privileged -v /:/host_root -w /host_root --network host alpine <cmd>
  4. Restart Docker / check kernel cgroup v2 support if the failure is runc-related

Example fix

// before
if err := d.client.ContainerStart(ctx, containerID, container.StartOptions{}); err != nil {
	return nil, fmt.Errorf("failed to start temporary container: %w", err)
}
// after
if err := d.client.ContainerStart(ctx, containerID, container.StartOptions{}); err != nil {
	return nil, fmt.Errorf("failed to start temporary container %s (cmd=%v): %w", containerID[:12], command, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the command exists inside the base image before starting
if _, err := d.client.ContainerInspect(ctx, containerID); err != nil {
	return fmt.Errorf("container not inspectable before start: %w", err)
}

Try / catch

res, err := docker.ExecHostCommand(ctx, cmd)
if err != nil && strings.Contains(err.Error(), "failed to start temporary container") {
	// runtime/start failure: check daemon + command binary, then retry once
	logger.Error("container start failed", "err", err)
}

Prevention

When it happens

Trigger: ContainerStart fails after ContainerCreate succeeded: image entrypoint/cmd rejected at runtime (e.g. command binary not present in alpine image), runtime errors like runc failures, port/network conflicts with NetworkMode host, cgroup or namespace permission errors, or the container being removed concurrently.

Common situations: Passing a command whose binary doesn't exist in alpine (e.g. bash instead of sh); AppArmor/SELinux denying privileged start; kernel lacking required features; Docker daemon's containerd shim crashing; stale container ID race when callers overlap.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/e768f02cdf49f8ec. Report an issue: GitHub.