opendataloader-project/opendataloader-pdf · error · IOException
pdf2img returned empty body
Error message
pdf2img returned empty body
What it means
The pdf2img endpoint returned 2xx but response.body() was null, so there is no JSON to parse for the page image. Like error 47 this points to a transport/proxy artifact rather than a content problem. It is a per-page IOException caught and logged by the table/figure handlers.
Source
Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/HancomAIClient.java:693
"odl-" + sourcePdfShaShort + "-pdf2img-p" + pageIndex)
.addFormDataPart("PAGE_INDEX", String.valueOf(pageIndex))
.addFormDataPart("FILE", DEFAULT_FILENAME,
RequestBody.create(pdfBytes, MEDIA_TYPE_PDF))
.build();
Request httpRequest = new Request.Builder()
.url(baseUrl + PDF2IMG_ENDPOINT)
.post(body)
.build();
try (Response response = httpClient.newCall(httpRequest).execute()) {
if (!response.isSuccessful()) {
throw new IOException("pdf2img returned HTTP " + response.code());
}
ResponseBody respBody = response.body();
if (respBody == null) {
throw new IOException("pdf2img returned empty body");
}
JsonNode root = objectMapper.readTree(respBody.string());
// Navigate: RESULT[0].RESULT.PAGE_PNG_DATA
JsonNode resultArr = root.get("RESULT");
if (resultArr == null || !resultArr.isArray() || resultArr.size() == 0) {
throw new IOException("pdf2img RESULT is empty");
}
JsonNode pageResult = resultArr.get(0);
JsonNode innerResult = pageResult.get("RESULT");
if (innerResult == null) {
throw new IOException("pdf2img inner RESULT is null");
}
String pngBase64 = innerResult.has("PAGE_PNG_DATA")
? innerResult.get("PAGE_PNG_DATA").asText() : null;
if (pngBase64 == null || pngBase64.isEmpty()) {View on GitHub (pinned to a7789b8e77)
Solutions
- Hit the backend pdf2img endpoint directly, bypassing proxies
- Confirm the backend returns 200 with a JSON body for pdf2img
- Retry the page render; transient null bodies are often connection artifacts
- Accept the per-page skip if it affects only some pages
Defensive patterns
Strategy: try-catch
Try / catch
try {
return cache.getOrFetch(pageNum, idx -> client.fetchPageImage(pdf, idx, crop));
} catch (IOException e) {
if ("pdf2img returned empty body".equals(e.getMessage())) {
// retry once — often a proxy/connection artifact
return cache.getOrFetch(pageNum, idx -> client.fetchPageImage(pdf, idx, crop));
}
log.warn("skipping page {}: {}", pageNum, e.getMessage());
continue;
} Prevention
- Avoid proxies between client and the pdf2img service
- Confirm the backend returns 200 with a JSON body, not 204
- Treat recurring empty bodies as a backend/proxy defect
When it happens
Trigger: POST to /support/pdf2img returns 2xx with a null ResponseBody inside fetchPageImage.
Common situations: A proxy/gateway between client and backend that strips or empties the body on the page render response; backend returning 204 by mistake; connection reuse closing the stream early.
Related errors
- pdf2img RESULT is empty
- pdf2img inner RESULT is null
- pdf2img PAGE_PNG_DATA is empty
- pdf2img PAGE_PNG_DATA is not valid Base64
- Empty response body
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/6fa0c5a5aaf5d2ce.
Report an issue: GitHub.