Tencent/WeKnora · error
read response body: %w
Error message
read response body: %w
What it means
After MinerU returns HTTP 200, callFileParse reads the full response body with io.ReadAll. If that read fails (connection reset mid-response, context cancellation, truncated chunked transfer, or a broken pipe to the MinerU server), the converter wraps the underlying error with this message. The request succeeded at the HTTP level but the response payload could not be received completely.
Source
Thrown at internal/infrastructure/docparser/mineru_converter.go:259
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 {
logger.Infof(context.Background(), "[MinerU] Raw response: %s", rawStr)
}
// Also pretty-print the top-level structure (without large base64 blobs)
var rawMap map[string]interface{}
if err := json.Unmarshal(respBody, &rawMap); err == nil {
c.logMinerUResponseStructure(rawMap, "")
}
mdContent, imagesB64, resultKey, err := parseMinerUFileParseResponse(respBody, uploadFileName)
if err != nil {View on GitHub (pinned to 988cbb0330)
Solutions
- Retry the parse request — transient resets usually succeed on a second attempt
- Increase the client timeout and any proxy idle/read timeouts between the app and MinerU
- Check that no reverse proxy (nginx/ingress) is buffering or truncating large responses
- Ensure the caller's context is not cancelled prematurely (increase upstream deadline)
- Verify network stability/DNS to the MinerU host
Example fix
// before
client := &http.Client{Timeout: 10 * time.Second}
// after
client := &http.Client{Timeout: 300 * time.Second} // allow large MinerU responses to stream Defensive patterns
Strategy: retry
Validate before calling
client := &http.Client{Timeout: 300 * time.Second}
req, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, body)
if _, err := client.Do(req); err != nil {
if errors.Is(err, context.DeadlineExceeded) { /* increase deadline */ }
} Type guard
func isBodyReadError(err error) bool {
return err != nil && strings.Contains(err.Error(), "read response body")
} Try / catch
result, err := callFileParse(ctx, file)
if isBodyReadError(err) {
result, err = retryWithBackoff(3, callFileParse, ctx, file)
}
if err != nil { return err } Prevention
- Set generous client timeouts for large parsed documents
- Align proxy idle timeouts with expected response duration
- Check context cancellation propagation before long parses
- Prefer streaming reads over long-lived idle connections
When it happens
Trigger: io.ReadAll(resp.Body) in callFileParse returns an error: network interruption after headers, MinerU closing the connection mid-body, context deadline exceeded while streaming a large parsed document, or proxy/gateway cutting the chunked response.
Common situations: Very large documents whose parsed JSON/zip takes long to stream and hits an idle-timeout on a proxy; unstable network to a remote MinerU instance; context canceled because the user request was aborted upstream.
Related errors
- read body failed: %w
- read response body: %w
- http read status %d: %s
- read body: %w
- read poll response body: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/7c2cf925c17c94d7.
Report an issue: GitHub.