Tencent/WeKnora · error

HTTP request: %w

Error message

HTTP request: %w

What it means

The SSRF-safe HTTP client failed to execute the POST to MinerU's /file_parse endpoint. This wraps transport-level failures: DNS resolution errors, connection refused/reset, TLS errors, timeouts, or blocked redirects — not an HTTP error status (non-200 produces the separate 'MinerU API status' error).

Source

Thrown at internal/infrastructure/docparser/mineru_converter.go:248

	}
	if _, err := part.Write(content); err != nil {
		return "", nil, fmt.Errorf("write file content: %w", err)
	}
	writer.Close()

	httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, c.endpoint+"/file_parse", &body)
	if err != nil {
		return "", nil, fmt.Errorf("create request: %w", err)
	}
	httpReq.Header.Set("Content-Type", writer.FormDataContentType())

	client := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{
		Timeout:      mineruTimeout,
		MaxRedirects: 5,
	})
	resp, err := client.Do(httpReq)
	if err != nil {
		return "", nil, fmt.Errorf("HTTP request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		respBody, _ := io.ReadAll(resp.Body)
		return "", nil, fmt.Errorf("MinerU API status %d: %s", resp.StatusCode, string(respBody))
	}

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", nil, fmt.Errorf("read response body: %w", err)
	}

	// Dump raw response for debugging (truncate if too large)
	rawStr := string(respBody)
	if len(rawStr) > 4000 {
		logger.Infof(context.Background(), "[MinerU] Raw response (truncated to 4000 chars): %s ...", rawStr[:4000])
	} else {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Unwrap the cause and check errors.Is(err, context.DeadlineExceeded) vs connection-refused to distinguish timeout vs unreachable host.
  2. Verify MinerU is up and the endpoint host:port is correct and reachable (curl http://<endpoint>/file_parse or a health route).
  3. If timeouts dominate, increase mineruTimeout or run parsing asynchronously with a longer budget.
  4. Check the SSRF-safe client's allowlist — private/internal MinerU hosts may be blocked by the SSRF guard; adjust its config.
  5. Fix TLS trust (add CA to the trust store) if the error is a certificate verification failure.
Defensive patterns

Strategy: try-catch

Try / catch

doc, err := conv.Read(ctx, req)
if err != nil && strings.Contains(err.Error(), "HTTP request") {
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() || errors.Is(err, context.DeadlineExceeded) {
        return fmt.Errorf("mineru timed out, requeue job: %w", err) // retry/async
    }
    if errors.Is(err, syscall.ECONNREFUSED) {
        return fmt.Errorf("mineru unreachable, check service/endpoint: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: client.Do(httpReq) returns a *url.Error: endpoint host unresolvable, connection refused (service down/wrong port), TLS certificate failure, mineruTimeout exceeded, or context canceled mid-request.

Common situations: MinerU container not running or on a different host/port than configured; DNS not resolving inside Kubernetes/Docker network; self-signed certificates without proper trust; document too large so the request exceeds mineruTimeout.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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