{"record":{"id":"2f0d5623da176fa7","repo":"juanfont/headscale","slug":"creating-docker-client-w-2f0d56","errorCode":null,"errorMessage":"creating Docker client: %w","messagePattern":"creating Docker client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/hi/stats.go","lineNumber":54,"sourceCode":"\tCPUUsage  float64 // CPU usage percentage\n\tMemoryMB  float64 // Memory usage in MB\n}\n\n// StatsCollector manages collection of container statistics.\ntype StatsCollector struct {\n\tclient            *client.Client\n\tcontainers        map[string]*ContainerStats\n\tstopChan          chan struct{}\n\twg                sync.WaitGroup\n\tmutex             sync.RWMutex\n\tcollectionStarted bool\n}\n\n// NewStatsCollector creates a new stats collector instance.\nfunc NewStatsCollector(ctx context.Context) (*StatsCollector, error) {\n\tcli, err := createDockerClient(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating Docker client: %w\", err)\n\t}\n\n\treturn &StatsCollector{\n\t\tclient:     cli,\n\t\tcontainers: make(map[string]*ContainerStats),\n\t\tstopChan:   make(chan struct{}),\n\t}, nil\n}\n\n// StartCollection begins monitoring all containers and collecting stats for hs- and ts- containers with matching run ID.\nfunc (sc *StatsCollector) StartCollection(ctx context.Context, runID string, verbose bool) error {\n\tsc.mutex.Lock()\n\tdefer sc.mutex.Unlock()\n\n\tif sc.collectionStarted {\n\t\treturn ErrStatsCollectionAlreadyStarted\n\t}\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/cmd/hi/stats.go#L36-L72","documentation":"client.NewClientWithOpts failed while constructing the Docker SDK client in NewStatsCollector. The client builder resolves its endpoint from the active docker context's endpoint host or DOCKER_HOST/DOCKER_TLS_SERVERCERT env vars (see createDockerClient at cmd/hi/docker.go:453) and errors when the host string is malformed or an unsupported protocol scheme is given. Note the SDK client is lazy — this failure is about client construction options, not daemon reachability.","triggerScenarios":"NewClientWithOpts rejecting an invalid host (bad DOCKER_HOST like 'tcp://:2375' or a scheme the SDK cannot handle, e.g. missing tcp://, npipe on Linux), unreadable TLS cert files, or an API version negotiation opt that fails to parse environment values.","commonSituations":"DOCKER_HOST set to a typo'd or Windows-style endpoint on Linux; a docker context whose endpoint metadata is malformed; leftover DOCKER_* env vars from a remote-daemon setup; running where the context config in ~/.docker/contexts is corrupted.","solutions":["Print and fix the environment: `echo $DOCKER_HOST` — it must be a valid scheme like unix:///var/run/docker.sock or tcp://host:2375","Check `docker context ls` and `docker context use default` to discard a broken context","Unset stale DOCKER_TLS_SERVERCERT/DOCKER_CERT_PATH values: `env -u DOCKER_TLS_SERVERCERT -u DOCKER_CERT_PATH go run ./cmd/hi ...`","Verify plain `docker info` works with the same environment"],"exampleFix":"# before\nexport DOCKER_HOST=:2375  # malformed, no scheme\ngo run ./cmd/hi run \"TestACL\"\n\n# after\nexport DOCKER_HOST=tcp://127.0.0.1:2375\ngo run ./cmd/hi run \"TestACL\"","handlingStrategy":"validation","validationCode":"if host := os.Getenv(\"DOCKER_HOST\"); host != \"\" {\n    u, err := url.Parse(host)\n    if err != nil || (u.Scheme != \"unix\" && u.Scheme != \"tcp\" && u.Scheme != \"npipe\") {\n        return fmt.Errorf(\"invalid DOCKER_HOST %q\", host)\n    }\n}\n_ = exec.LookPath(\"docker\") // sanity: CLI sees the same daemon","typeGuard":null,"tryCatchPattern":"cli, err := createDockerClient(ctx)\nif err != nil {\n    // construction errors are config/env problems — print env and docker context, do not retry\n    return nil, fmt.Errorf(\"creating Docker client: %w (check DOCKER_HOST=%q and `docker context ls`)\", err, os.Getenv(\"DOCKER_HOST\"))\n}","preventionTips":["Keep DOCKER_HOST either unset (local socket) or a fully-qualified unix:///tcp:// URL","Reset to a known context with `docker context use default` when switching daemons","Ensure `docker info` works in the same shell before running hi"],"tags":["docker","docker-sdk","configuration","env-vars"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}