Tencent/WeKnora · error
HTTP %d for %s
Error message
HTTP %d for %s
What it means
DownloadBytes requires an HTTP 200 response; any other status (404, 403, 500, redirects not followed to a 200, etc.) produces "HTTP <status> for <url>". The function treats non-OK as failure and returns no body.
Source
Thrown at internal/utils/httputil.go:31
MaxRedirects: 10,
})
// DownloadBytes fetches the content at the given HTTP(S) URL and returns the
// 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
- Verify the URL is correct and publicly accessible (curl -I it)
- Add required auth via a client that supports headers instead of DownloadBytes, or pre-sign the URL
- Handle the status code in the error message — retry 429/5xx with backoff, fail fast on 4xx
- Check for expired/rotated links (signed URLs past expiry return 403)
Example fix
// before
DownloadBytes("https://example.com/old-file.pdf") // 404
// after
resp, err := http.Head("https://example.com/file.pdf")
if err == nil && resp.StatusCode == http.StatusOK {
data, err := DownloadBytes("https://example.com/file.pdf")
} Defensive patterns
Strategy: retry
Validate before calling
resp, err := http.Head(url)
if err != nil || resp.StatusCode != http.StatusOK {
return fmt.Errorf("URL not downloadable (status %v)", resp)
} Try / catch
data, err := DownloadBytes(url)
if err != nil {
if strings.Contains(err.Error(), "HTTP ") {
var code int
if _, scanErr := fmt.Sscanf(err.Error(), "HTTP %d", &code); scanErr == nil {
if code == 429 || code >= 500 { /* retry with backoff */ } else { /* permanent — fix URL/auth */ }
}
}
} Prevention
- Pre-flight the URL with HEAD to catch 4xx before the full download
- Retry 429/5xx with exponential backoff; never retry 4xx client errors
- For authenticated assets, use signed URLs or a client that sends credentials
- Alert on links whose signed URLs may expire before use
When it happens
Trigger: Calling DownloadBytes against a URL that returns a non-200 status: missing resource, auth-required endpoint, rate limiting (429), server error, or a redirect chain not ending in 200 (the default client follows redirects, so this means the final response was non-200).
Common situations: Dead or moved download links, private assets requiring credentials, CDN rate limits, URLs behind login walls, or temporary upstream 5xx during deployments.
Related errors
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/87b65d639a932f42.
Report an issue: GitHub.