{"record":{"id":"06f38bd19b3b3ee2","repo":"vxcontrol/pentagi","slug":"failed-to-get-docker-info-w","errorCode":null,"errorMessage":"failed to get docker info: %w","messagePattern":"failed to get docker info: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"backend/pkg/docker/client.go","lineNumber":129,"sourceCode":"\t\tportsBase = BaseContainerPortsNumber\n\t}\n\tports := make([]int, containerPortsNumber)\n\tfor i := range containerPortsNumber {\n\t\tdelta := (int(flowID)*containerPortsNumber + i) % limitContainerPortsNumber\n\t\tports[i] = portsBase + delta\n\t}\n\treturn ports\n}\n\nfunc NewDockerClient(ctx context.Context, db database.Querier, cfg *config.Config) (DockerClient, error) {\n\tcli, err := client.New(client.FromEnv)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to initialize docker client: %w\", err)\n\t}\n\n\tinfoResult, err := cli.Info(ctx, client.InfoOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get docker info: %w\", err)\n\t}\n\tinfo := infoResult.Info\n\n\t// Resolve which host socket (if any) gets bind-mounted into worker containers.\n\t// Autodetection is skipped when DOCKER_INSIDE_HOST designates a daemon\n\t// endpoint for sandboxes: mounting the host socket alongside it would grant an\n\t// agent control of the daemon running PentAGI itself.\n\tsocket, autodetectSocket := cfg.WorkerDockerSocket()\n\tif autodetectSocket {\n\t\tsocket = getHostDockerSocket(ctx, cli)\n\t}\n\tinside := cfg.DockerInside\n\tif inside {\n\t\tswitch {\n\t\tcase cfg.DockerSocket != \"\":\n\t\t\tlogrus.Infof(\"DOCKER_INSIDE=true: worker containers will be given Docker access \"+\n\t\t\t\t\"via the configured socket %q.\", cfg.DockerSocket)\n\t\tcase cfg.DockerInsideHost != \"\":","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/docker/client.go#L111-L147","documentation":"NewDockerClient builds a moby client from the environment and immediately calls cli.Info(ctx) as a health check that the Docker daemon is reachable and answering API requests. If that call fails (daemon down, wrong DOCKER_HOST, permission denied on the socket, API version mismatch), the constructor aborts and wraps the underlying error with \"failed to get docker info: %w\". It is the earliest signal that PentAGI cannot talk to a Docker daemon at all.","triggerScenarios":"client.New(client.FromEnv) succeeded (so a socket path was resolved) but cli.Info() returned an error: Docker daemon not running, DOCKER_HOST points at an unreachable TCP endpoint, the user lacks read/write permission on /var/run/docker.sock, or the daemon's API version is incompatible with the moby client.","commonSituations":"Running PentAGI outside Docker Compose without a local dockerd; running the container without mounting /var/run/docker.sock; DOCKER_HOST=tcp://... pointing at a daemon behind a firewall or TLS misconfiguration; running as a non-root user not in the 'docker' group; Rootless Docker or podman socket env vars not exported (DOCKER_HOST unset in a systemd service context).","solutions":["Verify the daemon is up: run 'docker info' with the same environment (same user, same DOCKER_HOST); fix the daemon if it fails.","Check DOCKER_HOST / DOCKER_SOCKET env vars and the mounted /var/run/docker.sock when running inside a container; mount the socket or set DOCKER_HOST correctly.","Fix socket permissions: add the user to the 'docker' group (usermod -aG docker $USER) or use rootless socket at /run/user/$UID/docker.sock.","If API version mismatch, set DOCKER_API_VERSION to the daemon's version or upgrade the daemon/client.","Restart dockerd (systemctl restart docker) after config or certificate changes."],"exampleFix":"// before\nexport DOCKER_HOST=tcp://127.0.0.1:2375  # daemon not listening there\n// after\nexport DOCKER_HOST=unix:///var/run/docker.sock  # or unset to use default socket","handlingStrategy":"validation","validationCode":"// Before constructing the client (or as a health gate):\ncli, err := client.New(client.FromEnv)\nif err != nil { return err }\nif _, err := cli.Info(ctx, client.InfoOptions{}); err != nil {\n    return fmt.Errorf(\"docker daemon unreachable (%v): check DOCKER_HOST and /var/run/docker.sock\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := NewDockerClient(ctx, db, cfg); err != nil {\n    if strings.Contains(err.Error(), \"failed to get docker info\") {\n        log.Fatalf(\"Docker daemon not reachable: %v — start dockerd or fix DOCKER_HOST\", err)\n    }\n    return err\n}","preventionTips":["Always run 'docker info' with the same user/env as the app before deploying.","Mount /var/run/docker.sock (or set DOCKER_HOST) explicitly in docker-compose.yml / Kubernetes manifests.","Add the app user to the 'docker' group or use a rootless socket.","Add a startup readiness probe that calls docker info and fails fast with a clear message.","Pin DOCKER_API_VERSION if daemon/client versions may drift."],"tags":["docker","daemon-unreachable","startup"],"backgroundTag":"docker-daemon-unreachable","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}