Tencent/WeKnora · error
HTTP GET: %w
Error message
HTTP GET: %w
What it means
This error wraps a transport-level failure of the HTTP GET performed during remote image download — the request could not be completed at all. The underlying error (DNS, dial, TLS, timeout, context cancellation) is preserved via %w.
Source
Thrown at internal/infrastructure/docparser/image_resolver.go:1017
images = append(images, mdImages...)
images = append(images, htmlImages...)
return markdown, images, nil
}
// downloadImage fetches an image from remoteURL using the provided SSRF-safe
// client. It validates Content-Type and enforces maxRemoteImageSize.
func downloadImage(ctx context.Context, client *http.Client, remoteURL string) (data []byte, mimeType string, err error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, remoteURL, nil)
if err != nil {
return nil, "", fmt.Errorf("create request: %w", err)
}
// Some CDNs require a browser-like User-Agent.
req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; WeKnora/1.0)")
resp, err := client.Do(req)
if err != nil {
return nil, "", fmt.Errorf("HTTP GET: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, "", fmt.Errorf("unexpected status %d", resp.StatusCode)
}
// Determine MIME type from Content-Type header.
ct := resp.Header.Get("Content-Type")
mimeType, _, _ = mime.ParseMediaType(ct)
if mimeType == "" {
mimeType = "application/octet-stream"
}
// Only allow image content types (or octet-stream which we sniff later).
if !strings.HasPrefix(mimeType, "image/") && mimeType != "application/octet-stream" {
return nil, "", fmt.Errorf("non-image content type: %s", mimeType)
}View on GitHub (pinned to 988cbb0330)
Solutions
- Unwrap and classify the error (net.Error timeout, DNS, TLS) before retrying
- Verify the image host resolves and is reachable from the server (curl the URL)
- Check egress rules/proxy/timeout settings on the SSRF-safe HTTP client
- Retry only transient errors (timeouts, connection reset) with backoff
Example fix
// before
resp, err := client.Do(req)
if err != nil { return nil, "", fmt.Errorf("HTTP GET: %w", err) }
// after
resp, err := client.Do(req)
if err != nil {
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() {
return nil, "", fmt.Errorf("HTTP GET (timeout): %w", err)
}
return nil, "", fmt.Errorf("HTTP GET: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
// resolve host before fetching
if _, err := net.LookupHost(url.Host); err != nil {
return fmt.Errorf("host does not resolve: %w", err)
} Try / catch
data, mimeType, err := downloadImage(ctx, client, remoteURL)
if err != nil {
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() {
// retry once with longer timeout
}
if errors.Is(err, context.Canceled) {
return nil, "", err // do not retry cancellation
}
return nil, "", fmt.Errorf("HTTP GET: %w", err)
} Prevention
- Configure adequate timeouts on the SSRF-safe client
- Distinguish transient (timeout, reset) from permanent (DNS NXDOMAIN) errors before retrying
- Verify egress firewall/proxy rules allow outbound image fetches
- Honor context cancellation instead of retrying
When it happens
Trigger: downloadImage's client.Do fails: DNS resolution failure, connection refused, TLS handshake error, request timeout, or the context was cancelled while fetching the image.
Common situations: Image host unreachable or DNS broken, egress firewall blocking outbound requests, slow hosts exceeding the SSRF-safe client's timeout, caller cancelled the context mid-download.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- fetch failed: %w
- HTTP request: %w
- failed to execute request: %w
- failed to execute Metaso request: %w
- service unreachable: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/675b24e56df10027.
Report an issue: GitHub.