benbjohnson/litestream · error
failed to parse response: %w
Error message
failed to parse response: %w
What it means
On HTTP 200, Run unmarshals the body into litestream.InfoResponse. If json.Unmarshal fails, the response was not valid JSON or did not match the InfoResponse schema, and Run wraps the error with this message. It signals a client/server contract mismatch or corrupted payload.
Source
Thrown at cmd/litestream/info.go:69
}
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 {
return fmt.Errorf("failed to parse response: %w", err)
}
if *jsonOutput {
output, err := json.MarshalIndent(result, "", " ")
if err != nil {
return fmt.Errorf("failed to format response: %w", err)
}
fmt.Println(string(output))
} else {
uptime := time.Duration(result.UptimeSeconds) * time.Second
fmt.Printf("Litestream %s\n", result.Version)
fmt.Printf(" PID: %d\n", result.PID)
fmt.Printf(" Uptime: %s\n", uptime)
fmt.Printf(" Started at: %s\n", result.StartedAt.Format(time.RFC3339))
fmt.Printf(" Databases: %d\n", result.DatabaseCount)
}
return nilView on GitHub (pinned to 4ed7a308f6)
Solutions
- Restart the daemon so it matches the installed CLI version, then retry.
- Check `litestream version` (daemon logs) versus your CLI version and align them.
- Inspect the raw endpoint output (curl the /info endpoint) to see what is actually returned.
- Remove intermediaries that could rewrite or truncate the response body.
Example fix
// before $ litestream version # v0.5 CLI $ ps # daemon still old binary from before upgrade // after $ systemctl restart litestream # daemon now runs new binary $ litestream info
Defensive patterns
Strategy: try-catch
Validate before calling
// verify versions before calling
const { stdout } = await exec('litestream version');
const daemonVersion = await readDaemonVersionFromLogs();
if (stdout.trim() !== daemonVersion.trim()) throw new Error('CLI/daemon version mismatch; restart daemon'); Try / catch
var result litestream.InfoResponse
if err := json.Unmarshal(body, &result); err != nil {
// contract mismatch or corrupt payload: dump body, restart daemon to align versions, retry
log.Printf("bad /info payload: %v; body=%q", err, body)
return retryAfterDaemonRestart()
} Prevention
- Restart the daemon after every litestream upgrade so CLI and daemon versions match.
- Test the endpoint with curl after upgrades to confirm the JSON shape.
- Avoid intermediaries that can rewrite response bodies.
When it happens
Trigger: Daemon returns 200 with an empty or malformed body; the running daemon is an older/newer version whose /info JSON schema differs from the CLI's InfoResponse struct; a proxy mangles the body.
Common situations: Upgraded CLI binary while the daemon process still runs an older version; partial response truncated at a JSON boundary (rare); custom builds where the endpoint output changed.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse response: %w
- failed to parse response: %w
- heartbeat URL must be a valid HTTP or HTTPS URL
- failed to format response: %w
- failed to read response: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/962681eef64af9ac.
Report an issue: GitHub.