{"record":{"id":"7f0127e291a09778","repo":"benbjohnson/litestream","slug":"failed-to-read-response-w","errorCode":null,"errorMessage":"failed to read response: %w","messagePattern":"failed to read response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/info.go","lineNumber":56,"sourceCode":"\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 {\n\t\treturn fmt.Errorf(\"failed to parse response: %w\", err)\n\t}\n\n\tif *jsonOutput {\n\t\toutput, err := json.MarshalIndent(result, \"\", \"  \")\n\t\tif err != nil {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/info.go#L38-L74","documentation":"After a successful HTTP GET to the control socket's /info endpoint, Run reads the entire response body with io.ReadAll. If the read fails (connection dropped mid-response, truncated body), the error is wrapped with this message. It indicates a transport-level problem after headers were received, not a server-side logical error.","triggerScenarios":"Daemon closes the connection before sending the full body; network interruption or socket timeout hitting while reading the body; proxy/intermediary truncating the response.","commonSituations":"Daemon restarting concurrently with the info request; aggressive external timeout killing the socket mid-stream; flaky port-forward in container/Kubernetes setups.","solutions":["Simply retry `litestream info`; transient truncation usually resolves once the daemon is stable.","Increase --timeout (e.g. --timeout 60) if the response is being cut off before completion.","Check daemon logs for panics or restarts around the time of the request and fix the underlying crash.","Remove any proxy between the client and the socket that could truncate responses."],"exampleFix":"// before\n$ litestream info  # flaky port-forward truncates body\n// after\n$ kubectl port-forward pod/litestream 8080:8080  # re-establish stable forward\n$ litestream info","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := client.Get(\"http://localhost/info\")\nif err == nil {\n    body, err := io.ReadAll(resp.Body)\n    resp.Body.Close()\n    if err != nil {\n        // truncated read: transient — retry with backoff and a larger timeout\n        return retryWithBackoff(func() error { return runInfo(ctx) }, 3)\n    }\n}","preventionTips":["Use a generous --timeout so slow responses complete instead of being cut off.","Avoid proxies/port-forwards on the info path; connect directly to the socket endpoint.","Watch daemon logs for restarts that would truncate in-flight responses."],"tags":["network","io","http"],"backgroundTag":"file-read-failed","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"}