{"record":{"id":"b7e919d807f89203","repo":"wagoodman/dive","slug":"failed-to-get-docker-connection-helper-w","errorCode":null,"errorMessage":"failed to get docker connection helper: %w","messagePattern":"failed to get docker connection helper: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dive/image/docker/engine_resolver.go","lineNumber":84,"sourceCode":"\treturn fmt.Errorf(\"unable to extract from image '%s': %+v\", id, err)\n}\n\nfunc (r *engineResolver) fetchArchive(ctx context.Context, id string) (io.ReadCloser, error) {\n\tvar err error\n\tvar dockerClient *client.Client\n\n\thost, err := determineDockerHost()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not determine docker host: %v\", err)\n\t}\n\tclientOpts := []client.Opt{client.FromEnv}\n\tclientOpts = append(clientOpts, client.WithHost(host))\n\n\tswitch strings.Split(host, \":\")[0] {\n\tcase \"ssh\":\n\t\thelper, err := connhelper.GetConnectionHelper(host)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get docker connection helper: %w\", err)\n\t\t}\n\t\tclientOpts = append(clientOpts, func(c *client.Client) error {\n\t\t\thttpClient := &http.Client{\n\t\t\t\tTransport: &http.Transport{\n\t\t\t\t\tDialContext: helper.Dialer,\n\t\t\t\t},\n\t\t\t}\n\t\t\treturn client.WithHTTPClient(httpClient)(c)\n\t\t})\n\n\t\tclientOpts = append(clientOpts, client.WithHost(host))\n\t\tclientOpts = append(clientOpts, client.WithDialContext(helper.Dialer))\n\n\tdefault:\n\n\t\tif os.Getenv(\"DOCKER_TLS_VERIFY\") != \"\" && os.Getenv(\"DOCKER_CERT_PATH\") == \"\" {\n\t\t\tos.Setenv(\"DOCKER_CERT_PATH\", \"~/.docker\")\n\t\t}","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/wagoodman/dive/blob/d6c691947f8fda635c952a17ee3b7555379d58f0/dive/image/docker/engine_resolver.go#L66-L102","documentation":"Returned by engineResolver.fetchArchive (dive/image/docker/engine_resolver.go:84) when the resolved docker host starts with 'ssh:' and connhelper.GetConnectionHelper(host) fails. The connection helper parses the ssh:// DOCKER_HOST URL and prepares a dialer; invalid URLs or an unusable ssh setup make it error, wrapped here with %w.","triggerScenarios":"DOCKER_HOST=ssh://user@bad-host (unresolvable, typo'd scheme content), ssh:// with no user/host, an ssh binary that the helper cannot locate, or key/endpoint forms the helper rejects.","commonSituations":"Remote docker over SSH where the remote user or port is encoded incorrectly (helper expects ssh://user@host:port form; DOCKER_HOST=ssh://host without keys, or leftover windows-style paths); firewalled or renamed remote hosts after a config was written.","solutions":["Prove plain ssh works first: ssh -v <user>@<host> docker version - the same connection the helper will make","Fix the DOCKER_HOST format: ssh://user@host:port (note port after host, not ssh://host:22/user)","Ensure a local ssh client exists and keys/agent are available in the environment dive runs in (CI agents often lack the agent socket)","Unwrap the error for the precise cause - %w preserves connhelper's message"],"exampleFix":"# before\nexport DOCKER_HOST=ssh://docker@remote:2375   # 2375 is not an ssh port\n\n# after (ssh on port 2222, remote dockerd via its socket)\nexport DOCKER_HOST=ssh://docker@remote:2222\nssh -p 2222 docker@remote docker version  # verify before running dive","handlingStrategy":"validation","validationCode":"// validate an ssh:// DOCKER_HOST before dive runs\nhost := os.Getenv(\"DOCKER_HOST\")\nif strings.HasPrefix(host, \"ssh://\") {\n    u, err := url.Parse(host)\n    if err != nil || u.User == nil && u.Hostname() == \"\" {\n        return fmt.Errorf(\"invalid DOCKER_HOST %q\", host)\n    }\n    // prove ssh itself works with the same destination:\n    if err := exec.Command(\"ssh\", strings.TrimPrefix(host, \"ssh://\"), \"true\").Run(); err != nil {\n        return fmt.Errorf(\"ssh to docker host fails: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"reader, err := resolver.Fetch(ctx, id)\nif err != nil {\n    var helperErr *net.OpError // unwrap chain as needed; connhelper errors are plain fmt.Errorf\n    if strings.Contains(err.Error(), \"failed to get docker connection helper\") {\n        return fmt.Errorf(\"bad DOCKER_HOST=%q; expected ssh://user@host[:port] and a working ssh key\", os.Getenv(\"DOCKER_HOST\"))\n    }\n    return err\n}","preventionTips":["Format DOCKER_HOST as ssh://user@host:port","Test 'ssh <host> docker version' manually before wiring it into DOCKER_HOST","Ensure ssh keys/agent are available in the CI environment dive runs in"],"tags":["docker","ssh","remote-docker","network","configuration"],"backgroundTag":null,"analyzedSha":"d6c691947f8fda635c952a17ee3b7555379d58f0","analyzedAt":"2026-08-15T09:42:35.293Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}