benbjohnson/litestream · error
failed to connect to control socket: %w
Error message
failed to connect to control socket: %w
What it means
The `litestream start` CLI failed to make an HTTP POST to the daemon's control API. The client dials a Unix socket (default /var/run/litestream.sock) via a custom Transport, so any dial error, timeout, or connection reset surfaces here wrapped as 'failed to connect to control socket'. It means the CLI could not reach the running litestream daemon at all — the request never got a response.
Source
Thrown at cmd/litestream/start.go:65
Transport: &http.Transport{
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
return net.DialTimeout("unix", *socketPath, clientTimeout)
},
},
}
req := litestream.StartRequest{
Path: dbPath,
Timeout: *timeout,
}
reqBody, err := json.Marshal(req)
if err != nil {
return fmt.Errorf("failed to marshal request: %w", err)
}
resp, err := client.Post("http://localhost/start", "application/json", bytes.NewReader(reqBody))
if err != nil {
return fmt.Errorf("failed to connect to control socket: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
var errResp litestream.ErrorResponse
if err := json.Unmarshal(body, &errResp); err == nil && errResp.Error != "" {
return fmt.Errorf("start failed: %s", errResp.Error)
}
return fmt.Errorf("start failed: %s", string(body))
}
var result litestream.StartResponse
if err := json.Unmarshal(body, &result); err != nil {View on GitHub (pinned to 4ed7a308f6)
Solutions
- Verify the litestream daemon is running and was started with socket.enabled: true in its config
- Pass -socket with the exact same path the daemon listens on (default /var/run/litestream.sock)
- Check the socket file exists and is accessible: ls -l /var/run/litestream.sock
- Increase -timeout if the daemon is slow to accept connections
- Run the CLI in the same host/container/namespace as the daemon
Example fix
// before litestream start /path/to/db // after # start daemon with IPC socket enabled (config: socket.enabled: true), then: litestream start -socket /var/run/litestream.sock -timeout 30 /path/to/db
Defensive patterns
Strategy: fallback
Validate before calling
if [ ! -S /var/run/litestream.sock ]; then echo 'control socket missing — is the daemon running with socket.enabled: true?'; exit 1; fi
Try / catch
if err := startCmd.Run(ctx, args); err != nil {
if strings.Contains(err.Error(), "failed to connect to control socket") {
// check daemon health / socket path before surfacing
}
} Prevention
- Enable socket.enabled: true in the daemon config before using start/stop commands
- Keep the -socket flag value identical on daemon and CLI
- Script a health probe against the socket before issuing commands
- Run CLI and daemon in the same mount namespace/container
When it happens
Trigger: Running `litestream start /path/to/db` when the daemon is not running, the -socket path does not match the daemon's socket (IPC socket is disabled by default — must enable socket.enabled: true in config), the socket file was deleted, or the -timeout seconds elapse before the dial/handshake completes.
Common situations: Operator forgot to enable the IPC socket in the daemon config or used a non-default -socket path on only one side; daemon crashed or was restarted; running the CLI in a different mount namespace/container than the daemon so /var/run/litestream.sock is absent; socket permission denied for the current user.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- failed to connect to control socket: %w
- failed to read response: %w
- failed to connect to control socket: %w
- failed to read response: %w
- register failed: %s
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/97fc89daef41577f.
Report an issue: GitHub.