vxcontrol/pentagi · error

container shutdown failed: %w

Error message

container shutdown failed: %w

What it means

StopContainer wraps any error from the Docker daemon's ContainerStop call that is not a 'not found'. It means the daemon accepted the request but failed to stop the container (or the connection to the daemon failed).

Source

Thrown at backend/pkg/docker/client.go:734

	_, err := dc.client.ContainerRemove(ctx, containerID, client.ContainerRemoveOptions{
		RemoveVolumes: true,
		Force:         true,
	})
	if err != nil && !cerrdefs.IsNotFound(err) {
		logger.WithError(err).Error("failed to remove the container that did not start")
	}
}

func (dc *dockerClient) StopContainer(ctx context.Context, containerID string, dbID int64) error {
	logger := dc.logger.WithContext(ctx).WithField("local_id", containerID)
	logger.Info("initiating container shutdown sequence")

	_, stopErr := dc.client.ContainerStop(ctx, containerID, client.ContainerStopOptions{})
	if stopErr != nil {
		if cerrdefs.IsNotFound(stopErr) {
			logger.Warn("target container already removed or never existed")
		} else {
			return fmt.Errorf("container shutdown failed: %w", stopErr)
		}
	}

	_, err := dc.db.UpdateContainerStatus(ctx, database.UpdateContainerStatusParams{
		Status: database.ContainerStatusStopped,
		ID:     dbID,
	})
	if err != nil {
		return fmt.Errorf("database status update failed during container stop: %w", err)
	}

	logger.Info("container shutdown completed successfully")

	return nil
}

func (dc *dockerClient) RemoveContainer(ctx context.Context, containerID string, dbID int64) error {
	logger := dc.logger.WithContext(ctx).WithField("local_id", containerID)

View on GitHub (pinned to ea665308ba)

Solutions

  1. Verify the container state with `docker inspect -f '{{.State.Status}}' <id>` and unpause or force-kill manually if paused/dead
  2. Check the Docker daemon is healthy (`docker info`) and reachable from the PentAGI backend
  3. Retry StopContainer / fall through to RemoveContainer with Force:true, which force-kills the container
  4. Inspect dockerd logs (`journalctl -u docker`) for the underlying stop failure

Example fix

// before
_, stopErr := dc.client.ContainerStop(ctx, containerID, client.ContainerStopOptions{})
// after
_, stopErr := dc.client.ContainerStop(ctx, containerID, client.ContainerStopOptions{Timeout: &shortTimeout})
if stopErr != nil && !cerrdefs.IsNotFound(stopErr) {
    logger.WithError(stopErr).Warn("graceful stop failed, forcing kill")
    _ = dc.client.ContainerKill(ctx, containerID, "SIGKILL")
}
Defensive patterns

Strategy: retry

Validate before calling

// check daemon and container state before stopping
state, err := dockerCli.ContainerInspect(ctx, id)
if err == nil && state.Container.State != nil && state.Container.State.Paused {
    dockerCli.ContainerUnpause(ctx, id)
}

Type guard

func isNotFound(err error) bool { return cerrdefs.IsNotFound(err) }

Try / catch

if err := dc.StopContainer(ctx, id, dbID); err != nil {
    if !cerrdefs.IsNotFound(err) {
        log.WithError(err).Warn("stop failed; forcing remove")
        _ = dc.RemoveContainer(ctx, id, dbID) // Force:true path
    }
}

Prevention

When it happens

Trigger: dc.client.ContainerStop returns a non-NotFound error: daemon unreachable mid-request, container in a state that cannot stop (paused, dead), timeout exceeded while graceful stop fails, or an API/network error between the client and dockerd.

Common situations: Docker daemon restarting or being upgraded while flows are torn down; container paused via `docker pause`; container already in 'dead' state; transient network failure to the Docker socket or TCP endpoint; cgroup/driver issues on the host preventing SIGKILL delivery.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/bb9e5fc3c6347f98. Report an issue: GitHub.