benbjohnson/litestream · error

failed to connect to control socket: %w

Error message

failed to connect to control socket: %w

What it means

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.

Source

Thrown at cmd/litestream/info.go:50

	}

	if *timeout <= 0 {
		return fmt.Errorf("timeout must be greater than 0")
	}

	clientTimeout := time.Duration(*timeout) * time.Second
	client := &http.Client{
		Timeout: clientTimeout,
		Transport: &http.Transport{
			DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
				return net.DialTimeout("unix", *socketPath, clientTimeout)
			},
		},
	}

	resp, err := client.Get("http://localhost/info")
	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("info failed: %s", errResp.Error)
		}
		return fmt.Errorf("info failed: %s", string(body))
	}

	var result litestream.InfoResponse
	if err := json.Unmarshal(body, &result); err != nil {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Verify the litestream daemon is running (ps / systemctl status litestream) and start it if not.
  2. Enable the control socket in the config: set `socket.enabled: true` under the socket section, then restart litestream.
  3. Check the configured socket address/port matches what the client dials; correct the endpoint or port.
  4. If running in a container, ensure you are inside the same network namespace as the daemon or expose/forward the socket endpoint.

Example fix

# before (litestream.yml)
dbs:
  - path: /var/lib/app.db
# after
socket:
  enabled: true
dbs:
  - path: /var/lib/app.db
Defensive patterns

Strategy: retry

Validate before calling

// preflight: check daemon reachable
const net = require('net');
const s = net.connect(socketPort, '127.0.0.1');
s.on('connect', () => { console.log('socket up'); s.end(); });
s.on('error', () => console.error('daemon not reachable; enable socket.enabled and start litestream'));

Try / catch

out, err := runInfo(ctx)
if err != nil {
    var opErr *net.OpError
    if errors.As(err, &opErr) && errors.Is(opErr.Err, syscall.ECONNREFUSED) {
        // daemon down or socket disabled: alert / start daemon, then retry with backoff
        return retryWithBackoff(runInfo, 3)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/4278cddc75735445. Report an issue: GitHub.