opendataloader-project/opendataloader-pdf · error · IOException

Empty response body from visualinfo

Error message

Empty response body from visualinfo

What it means

The visualinfo endpoint returned a successful (2xx) HTTP status but response.body() is null. This mirrors error 64 (same condition on the upload endpoint) — the server claims success but provides no JSON body to parse for visual info data. This is a transport-level anomaly, not a business-logic error.

Source

Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/HancomClient.java:243

            "?engine=" + ENGINE +
            "&dlaMode=" + DLA_MODE +
            "&ocrMode=" + OCR_MODE;

        Request request = new Request.Builder()
            .url(url)
            .get()
            .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                ResponseBody body = response.body();
                String bodyStr = body != null ? body.string() : "";
                throw new IOException("Hancom visualinfo failed with status " + response.code() + ": " + bodyStr);
            }

            ResponseBody body = response.body();
            if (body == null) {
                throw new IOException("Empty response body from visualinfo");
            }

            return objectMapper.readTree(body.string());
        }
    }

    /**
     * Deletes an uploaded file from the server.
     *
     * <p>This method silently ignores any errors to ensure cleanup
     * doesn't interfere with the main processing result.
     *
     * @param fileId The file ID to delete.
     */
    private void deleteFile(String fileId) {
        String url = baseUrl + String.format(DELETE_ENDPOINT, fileId);

        Request request = new Request.Builder()

View on GitHub (pinned to a7789b8e77)

Solutions

  1. Retry the getVisualInfo call — this is typically a transient transport issue.
  2. Check proxy configurations for response body size limits or buffering settings.
  3. Test the endpoint directly with curl bypassing any proxy: `curl -s '<visualinfo-url>?fileId=...'`.
  4. Add an OkHttp logging interceptor to capture response headers (Content-Length, Transfer-Encoding) for diagnosis.
  5. If persistent, escalate to Hancom support — a 2xx with empty body violates the API contract.

Example fix

// No client-side fix — this is a server/proxy anomaly.
// Best practice: retry once and log response headers.
Response response = httpClient.newCall(request).execute();
if (response.isSuccessful() && response.body() == null) {
    LOGGER.severe("Visualinfo succeeded (HTTP " + response.code() + ") but body is null.");
    throw new IOException("Empty response body from visualinfo");
}
Defensive patterns

Strategy: retry

Validate before calling

// Cannot pre-validate server response body existence.
// Enable OkHttp connection failure retry:
OkHttpClient client = new OkHttpClient.Builder()
    .retryOnConnectionFailure(true)
    .build();

Try / catch

try {
    JsonNode visualInfo = client.getVisualInfo(fileId);
} catch (IOException e) {
    if (e.getMessage().contains("Empty response body")) {
        // Transient — retry once
        visualInfo = client.getVisualInfo(fileId);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling HancomClient.getVisualInfo(fileId) when the server returns a 200/204 with no entity body, or the response stream is prematurely closed at the network layer. Unlike error 67 (non-2xx), the HTTP status indicates success but the body is absent.

Common situations: Reverse proxy (nginx, HAProxy) buffering or stripping response bodies for large JSON payloads; server-side timeout during visual info serialization causes the handler to return before writing the body; HTTP/2 stream reset after headers; intermediate caching layer serving a stale empty response.

Related errors


AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14). Data as JSON: /api/errors/5f0da577b38a9342. Report an issue: GitHub.