Billionmail/BillionMail · error

failed waiting for container execution: %w

Error message

failed waiting for container execution: %w

What it means

ExecHostCommand registers ContainerWait with WaitConditionNotRunning and selects on the error channel; a non-nil error from the wait stream is wrapped as 'failed waiting for container execution'. This means the Docker API errored while streaming wait state — usually the container was removed, the daemon restarted, or the context was cancelled — not that the command exited non-zero (that is reported via result.ExitCode).

Source

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

		"",
	)
	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,
	}
	logs, err := d.client.ContainerLogs(ctx, containerID, options)
	if err != nil {
		result.Error = fmt.Sprintf("failed to get command output: %v", err)
	} else {
		defer logs.Close()
		var buf bytes.Buffer
		_, err := io.Copy(&buf, logs)
		if err != nil {

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Check the wrapped error for context.DeadlineExceeded/Canceled and extend or remove the ctx timeout for long commands
  2. Ensure nothing else removes or manages these anonymous containers while they run (cleanupContainer is already deferred)
  3. Verify daemon stability (uptime, journalctl -u docker) if the connection dropped mid-wait
  4. Retry the command once transiently — the temp container is auto-cleaned so retry is safe

Example fix

// before
statusCh, errCh := d.client.ContainerWait(ctx, containerID, container.WaitConditionNotRunning)
// after: use a detached context for waiting so HTTP client deadlines don't abort the stream
statusCh, errCh := d.client.ContainerWait(context.WithoutCancel(ctx), containerID, container.WaitConditionNotRunning)
Defensive patterns

Strategy: retry

Validate before calling

// bound the work: avoid waiting on long commands with a short ctx
cmdCtx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()

Try / catch

res, err := docker.ExecHostCommand(ctx, cmd)
if err != nil {
	if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
		// timeout: reschedule or escalate
	} else if strings.Contains(err.Error(), "failed waiting for container execution") {
		// transient daemon/transport error: safe to retry, temp container auto-cleaned
		res, err = docker.ExecHostCommand(ctx, cmd)
	}
}

Prevention

When it happens

Trigger: Calling ExecHostCommand/ExecHostShellCommand (or addNewRules/deleteOldRules) when: the passed ctx is cancelled/times out during ContainerWait; the daemon drops the connection; the container is killed/removed externally while waiting; containerd reports a wait error.

Common situations: Long-running host commands exceeding an HTTP/request context deadline; Docker daemon restart mid-execution; someone running docker rm on the temp container; OOM killer terminating the container causing a wait-stream error on some daemon versions.

Related errors


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