Tencent/WeKnora · warning
read body: %w
Error message
read body: %w
What it means
DownloadBytes reads the entire response body with io.ReadAll after confirming status 200; an I/O failure mid-read (connection reset, premature close, truncated chunked encoding) is wrapped as "read body: <cause>".
Source
Thrown at internal/utils/httputil.go:35
// raw bytes. It reuses a package-level http.Client with a 60-second timeout.
func DownloadBytes(url string) ([]byte, error) {
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
return nil, fmt.Errorf("unsupported URL scheme: %s", url)
}
if err := ValidateURLForSSRF(url); err != nil {
return nil, fmt.Errorf("URL rejected by SSRF policy: %w", err)
}
resp, err := defaultHTTPClient.Get(url)
if err != nil {
return nil, fmt.Errorf("HTTP GET: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP %d for %s", resp.StatusCode, url)
}
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read body: %w", err)
}
return data, nil
}
View on GitHub (pinned to 988cbb0330)
Solutions
- Retry the download with exponential backoff — transient resets often succeed on retry
- Use a resumable/range-request download for large files
- Verify intermediate proxies/CDNs aren't truncating the response
- Check server-side stability of the endpoint; for huge payloads consider a different transfer mechanism (fetch in chunks)
Example fix
// before
data, err := DownloadBytes(url) // read body: unexpected EOF
// after
var data []byte
err := retryWithBackoff(3, func() error {
var e error
data, e = DownloadBytes(url)
return e
}) Defensive patterns
Strategy: retry
Try / catch
var data []byte
err := retryWithBackoff(3, time.Second, func() error {
var e error
data, e = DownloadBytes(url)
if e != nil && strings.Contains(e.Error(), "read body:") {
return e // transient truncation — retry
}
return e
}) Prevention
- Retry truncated reads with backoff — mid-body resets are usually transient
- Use chunked/range resumable downloads for large payloads
- Check intermediate proxies/CDNs/LBs for idle-timeout truncation
- Avoid downloading very large bodies on unstable network paths
When it happens
Trigger: Calling DownloadBytes when the connection drops while streaming the body: server closes prematurely, network interruption, proxy/CDN truncation, or chunked encoding errors.
Common situations: Flaky mobile/satellite uplinks on the server side, large downloads over unstable connections, aggressive LB idle timeouts killing long transfers, or misbehaving CDNs/proxies cutting responses short.
Related errors
- read response body: %w
- read poll response body: %w
- fetch failed: %w
- read body failed: %w
- execute request: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/322af64bac9ee08f.
Report an issue: GitHub.