{"record":{"id":"4278cddc75735445","repo":"benbjohnson/litestream","slug":"failed-to-connect-to-control-socket-w","errorCode":null,"errorMessage":"failed to connect to control socket: %w","messagePattern":"failed to connect to control socket: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/info.go","lineNumber":50,"sourceCode":"\t}\n\n\tif *timeout <= 0 {\n\t\treturn fmt.Errorf(\"timeout must be greater than 0\")\n\t}\n\n\tclientTimeout := time.Duration(*timeout) * time.Second\n\tclient := &http.Client{\n\t\tTimeout: clientTimeout,\n\t\tTransport: &http.Transport{\n\t\t\tDialContext: func(_ context.Context, _, _ string) (net.Conn, error) {\n\t\t\t\treturn net.DialTimeout(\"unix\", *socketPath, clientTimeout)\n\t\t\t},\n\t\t},\n\t}\n\n\tresp, err := client.Get(\"http://localhost/info\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to connect to control socket: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read response: %w\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tvar errResp litestream.ErrorResponse\n\t\tif err := json.Unmarshal(body, &errResp); err == nil && errResp.Error != \"\" {\n\t\t\treturn fmt.Errorf(\"info failed: %s\", errResp.Error)\n\t\t}\n\t\treturn fmt.Errorf(\"info failed: %s\", string(body))\n\t}\n\n\tvar result litestream.InfoResponse\n\tif err := json.Unmarshal(body, &result); err != nil {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/info.go#L32-L68","documentation":"The info command issues an HTTP GET to http://localhost/info against the litestream IPC/control socket (the unix socket is bridged to this local HTTP endpoint, enabled by `socket.enabled: true` in config). If the HTTP client cannot establish a connection, Run wraps the error with this message. Since the socket is disabled by default, this is the most common failure of the info command.","triggerScenarios":"Litestream daemon is not running; the control socket is disabled in the config (socket.enabled not set to true); the client points at the wrong port/address; the daemon listens on a different host/port than localhost.","commonSituations":"Running `litestream info` in a fresh deployment where the config lacks the socket section; daemon crashed or was restarted; SELinux/container networking blocking loopback; querying a remote host's litestream from a machine where 'localhost' refers to the wrong host.","solutions":["Verify the litestream daemon is running (ps / systemctl status litestream) and start it if not.","Enable the control socket in the config: set `socket.enabled: true` under the socket section, then restart litestream.","Check the configured socket address/port matches what the client dials; correct the endpoint or port.","If running in a container, ensure you are inside the same network namespace as the daemon or expose/forward the socket endpoint."],"exampleFix":"# before (litestream.yml)\ndbs:\n  - path: /var/lib/app.db\n# after\nsocket:\n  enabled: true\ndbs:\n  - path: /var/lib/app.db","handlingStrategy":"retry","validationCode":"// preflight: check daemon reachable\nconst net = require('net');\nconst s = net.connect(socketPort, '127.0.0.1');\ns.on('connect', () => { console.log('socket up'); s.end(); });\ns.on('error', () => console.error('daemon not reachable; enable socket.enabled and start litestream'));","typeGuard":null,"tryCatchPattern":"out, err := runInfo(ctx)\nif err != nil {\n    var opErr *net.OpError\n    if errors.As(err, &opErr) && errors.Is(opErr.Err, syscall.ECONNREFUSED) {\n        // daemon down or socket disabled: alert / start daemon, then retry with backoff\n        return retryWithBackoff(runInfo, 3)\n    }\n    return err\n}","preventionTips":["Set `socket.enabled: true` in the litestream config before relying on `litestream info`.","Add a health check that verifies the daemon is running before invoking info.","In containers, keep the client and daemon in the same network namespace or forward the socket.","Monitor the daemon with systemd/supervisor so it is restarted on crash."],"tags":["network","ipc","socket"],"backgroundTag":"connection-refused","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}