opendataloader-project/opendataloader-pdf · error · IOException
pdf2img returned HTTP %s
Error message
pdf2img returned HTTP %s
What it means
fetchPageImage posts the PDF page to the /support/pdf2img endpoint; a non-2xx status is converted to IOException. This is a per-page render error: callers (recognizeTableStructures, captionFigures) catch IOException and skip just that page with a WARNING, so it degrades rather than aborts the whole conversion unless it escapes.
Source
Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/HancomAIClient.java:688
private BufferedImage fetchPageImage(byte[] pdfBytes, int pageIndex, CropOutput cropOutput)
throws IOException {
MultipartBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("REQUEST_ID",
"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");View on GitHub (pinned to a7789b8e77)
Solutions
- Check the backend pdf2img service logs for the failing page index
- Confirm PAGE_INDEX is 0/1-based as the backend expects
- Retry the page (the cache will re-fetch on next getOrFetch after the corrupt entry is cleared)
- Accept the degraded result: affected tables/figures are skipped with a WARNING
- Restart the backend pdf2img component if it crashed
Defensive patterns
Strategy: try-catch
Validate before calling
// Before relying on page images, sanity-check page range against the PDF
if (pageIndex < 0 || pageIndex >= pageCount) {
throw new IllegalArgumentException("page index out of range: " + pageIndex);
} Try / catch
// fetchPageImage is called via the cache; per-page handlers already catch:
try {
pageImage = cache.getOrFetch(pageNum, idx -> client.fetchPageImage(pdf, idx, crop));
} catch (IOException e) {
log.warn("skipping page {}: {}", pageNum, e.getMessage());
continue; // degrade gracefully, skip this page's tables/figures
} Prevention
- Confirm PAGE_INDEX base (0 vs 1) matches the backend
- Monitor backend pdf2img service health separately
- Accept per-page skips as degraded-but-complete output rather than aborting
When it happens
Trigger: POST to baseUrl + '/support/pdf2img' with PAGE_INDEX and FILE returns a non-2xx HTTP code inside fetchPageImage's try-with-resources.
Common situations: pdf2img microservice down or misconfigured; page index out of range for the backend; backend cannot render a specific malformed page; backend resource limits hit on a large page.
Related errors
- Hancom AI server at %s returned HTTP %s
- Hybrid server at %s returned HTTP %s during health check. Th
- Docling Fast Server request failed with status %s: %s
- Hancom AI server is not available at %s Check that the serve
- pdf2img returned empty body
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/e8292fc25d516e12.
Report an issue: GitHub.