Tencent/WeKnora · error

download jsonl

Error message

download jsonl: %w

What it means

fetchResults downloads the JSONL result file from the provider using an SSRF-safe HTTP client; this error wraps any transport-level failure of that GET (DNS failure, connection refused/reset, TLS error, timeout after the 120s client timeout, or redirect issues). It is returned to Read, failing the parse even though the remote task itself succeeded.

Solutions

  1. Retry Read (or just the download) — transient network/CDN failures usually clear.
  2. Increase the SSRF-safe client Timeout above 120s if the JSONL result is very large or the link is slow.
  3. Verify egress connectivity: DNS resolution, proxy env vars (HTTP(S)_PROXY), and firewall rules for the result host.
  4. Check TLS validity of the result host (expired/mismatched certificate) with curl/openssl.
  5. If timeouts recur, stream the body to disk instead of io.ReadAll within one blocking request, or fetch via a resumable/ranged download.

Example fix

// before
client := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{Timeout: 120 * time.Second, MaxRedirects: 5})

// after: larger timeout plus caller-side retry
var data []byte
backoff := 2 * time.Second
for attempt := 0; attempt < 3; attempt++ {
    data, err = downloadJSONL(jsonlURL, 300*time.Second)
    if err == nil { break }
    time.Sleep(backoff)
    backoff *= 2
}
Defensive patterns

Strategy: retry

Validate before calling

// verify the result host is reachable and cert-valid before the full download
if err := utils.ValidateURLForSSRF(jsonlURL); err != nil {
    return err
}
conn, err := net.DialTimeout("tcp", hostOf(jsonlURL)+":443", 5*time.Second)
if err != nil { return fmt.Errorf("result host unreachable: %w", err) }
conn.Close()

Try / catch

data, err := downloadWithRetry(jsonlURL, 3, time.Second)
if err != nil && strings.Contains(err.Error(), "download jsonl") {
    // check network, DNS, proxy and TLS before surfacing to the user
    return fmt.Errorf("could not fetch OCR result (network?): %w", err)
}

Prevention

When it happens

Trigger: client.Get(jsonlURL) inside fetchResults returns a non-nil error after the task already completed and passed the SSRF check — network outage, DNS resolution failure, TLS handshake failure, or the 120-second client timeout elapsing on a very large result.

Common situations: Egress firewall/proxy blocking the result-hosting domain; DNS misconfiguration in containers/Kubernetes; very large JSONL results exceeding the 120s timeout on slow links; provider CDN returning connection resets; expired TLS certificates on the result host.

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


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/eb4db0a309ecc6b8. Report an issue: GitHub.

Appendix: source

Thrown at internal/infrastructure/docparser/paddleocr_vl_cloud_converter.go:271

type paddleOCRVLCloudResultLine struct {
	Result struct {
		LayoutParsingResults []struct {
			Markdown struct {
				Text   string            `json:"text"`
				Images map[string]string `json:"images"`
			} `json:"markdown"`
		} `json:"layoutParsingResults"`
	} `json:"result"`
}

func (c *PaddleOCRVLCloudReader) fetchResults(jsonlURL string) (string, map[string]string, error) {
	if err := utils.ValidateURLForSSRF(jsonlURL); err != nil {
		return "", nil, fmt.Errorf("jsonl URL blocked by SSRF check: %v", err)
	}
	client := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{Timeout: 120 * time.Second, MaxRedirects: 5})
	resp, err := client.Get(jsonlURL)
	if err != nil {
		return "", nil, fmt.Errorf("download jsonl: %w", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return "", nil, fmt.Errorf("download jsonl status %d", resp.StatusCode)
	}
	data, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", nil, fmt.Errorf("read jsonl body: %w", err)
	}

	texts := make([]string, 0)
	images := make(map[string]string)
	for _, line := range strings.Split(strings.TrimSpace(string(data)), "\n") {
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		}
		var parsed paddleOCRVLCloudResultLine

View on GitHub (pinned to 988cbb0330)