opendataloader-project/opendataloader-pdf · error · IOException
pdf2img PAGE_PNG_DATA is not valid Base64
Error message
pdf2img PAGE_PNG_DATA is not valid Base64
What it means
PAGE_PNG_DATA was present and non-empty but failed Base64 decoding (IllegalArgumentException). fetchPageImage wraps the IAE as IOException with a clear message, because the method signature only declares IOException and an escaping IAE would abort the entire conversion instead of just skipping the page. Indicates the payload is not valid Base64 (truncated, corrupted, or wrong encoding).
Source
Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/HancomAIClient.java:722
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()) {
throw new IOException("pdf2img PAGE_PNG_DATA is empty");
}
byte[] pngBytes;
try {
pngBytes = Base64.getDecoder().decode(pngBase64);
} catch (IllegalArgumentException e) {
// fetchPageImage is declared to throw IOException and callers catch
// only IOException. Escaping IAE would abort the whole conversion
// instead of skipping the failed page.
throw new IOException("pdf2img PAGE_PNG_DATA is not valid Base64", e);
}
BufferedImage image = ImageIO.read(new ByteArrayInputStream(pngBytes));
if (image == null) {
throw new IOException("pdf2img PAGE_PNG_DATA is not a readable image");
}
if (cropOutput.active()) {
savePageImageFile(cropOutput.directory(), pageIndex, pngBytes);
}
return image;
}
}
/**
* Sends a cropped image to IMAGE_CAPTIONING and returns the caption text.
*/
/** Image-captioning result: caption text + the model's self-reported confidence. */
static final class CaptionResult {
final String caption;View on GitHub (pinned to a7789b8e77)
Solutions
- Check whether the backend emits standard vs URL-safe Base64 and decode accordingly
- Strip any 'data:image/png;base64,' prefix if the backend adds one
- Bypass proxies that may truncate large base64 payloads
- Retry the page; transient truncation often clears
- Log the first/last chars of pngBase64 to diagnose format
Defensive patterns
Strategy: try-catch
Try / catch
try {
return cache.getOrFetch(pageNum, idx -> client.fetchPageImage(pdf, idx, crop));
} catch (IOException e) {
String m = e.getMessage();
if (m.contains("not valid Base64")) {
// possible URL-safe Base64 or data-URI prefix; retry with a tolerant decoder
log.warn("page {} base64 decode failed — check backend encoding", pageNum);
}
continue;
} Prevention
- Confirm the backend emits standard (MIME) Base64, not URL-safe or a data-URI prefix
- Bypass proxies that may truncate large base64 payloads
- Retry once — transient truncation often clears on the next request
When it happens
Trigger: Base64.getDecoder().decode(pngBase64) throws IllegalArgumentException on the PAGE_PNG_DATA string inside fetchPageImage; the catch re-throws it as IOException.
Common situations: Truncated response body from a proxy cutting large images; backend returning URL-safe Base64 while the client uses standard decoder; corrupted transfer; backend bug emitting raw bytes or a data-URI prefix.
Related errors
- pdf2img returned empty body
- pdf2img RESULT is empty
- pdf2img inner RESULT is null
- pdf2img PAGE_PNG_DATA is empty
- pdf2img returned HTTP %s
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/15a51d87cdd38945.
Report an issue: GitHub.