Billionmail/BillionMail · error

failed to list containers: %w

Error message

failed to list containers: %w

What it means

ListContainer wraps any error returned by public.DockerApiFromCtx(ctx).ListContainers(ctx) with 'failed to list containers: %w'. It is a controller-level passthrough: the Docker API client could not enumerate containers, and the root cause (connection, socket, daemon) is preserved via %w.

Source

Thrown at core/internal/controller/dockerapi/dockerapi_v1_list_container.go:16

package dockerapi

import (
	"billionmail-core/api/dockerapi/v1"
	"billionmail-core/internal/service/public"
	"context"
	"fmt"
)

func (c *ControllerV1) ListContainer(ctx context.Context, req *v1.ListContainerReq) (res *v1.ListContainerRes, err error) {
	res = &v1.ListContainerRes{}

	res.Data, err = public.DockerApiFromCtx(ctx).ListContainers(ctx)

	if err != nil {
		return nil, fmt.Errorf("failed to list containers: %w", err)
	}

	res.SetSuccess(public.LangCtx(ctx, "Success"))

	return
}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Check the wrapped cause (%w) in the returned error — it names the real failure (connection refused, permission denied, no such file).
  2. Verify the Docker daemon is running: 'docker ps' on the host.
  3. If running in a container, mount the socket: -v /var/run/docker.sock:/var/run/docker.sock (or expose DOCKER_HOST to a TCP endpoint).
  4. Fix socket permissions: add the service user to the 'docker' group or relax socket perms.

Example fix

// before
docker run billionmail   # socket not mounted -> failed to list containers
// after
docker run -v /var/run/docker.sock:/var/run/docker.sock billionmail
Defensive patterns

Strategy: try-catch

Validate before calling

sock := os.Getenv("DOCKER_HOST")
if sock == "" {
	if _, err := os.Stat("/var/run/docker.sock"); err != nil {
		return fmt.Errorf("docker socket not available: %w", err)
	}
}
// optional pre-check:
// cli.Ping(ctx) before ListContainers

Try / catch

res, err := client.ListContainer(ctx, req)
if err != nil {
	if strings.Contains(err.Error(), "permission denied") {
		return fmt.Errorf("docker socket access denied: add user to docker group or mount the socket")
	}
	if strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "no such file") {
		return fmt.Errorf("docker daemon unreachable: is it running and the socket mounted?")
	}
	return err
}

Prevention

When it happens

Trigger: Any error from the Docker Engine API call inside ListContainers — Docker daemon not running, unix socket /var/run/docker.sock missing or permission-denied, Docker API unreachable from inside a container (volume not mounted), or API timeout.

Common situations: Docker Desktop stopped; app deployed without mounting the docker socket; user not in the 'docker' group (permission denied on socket); DOCKER_HOST misconfigured; Docker daemon restart during the call.

Related errors


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