opendataloader-project/opendataloader-pdf · error · IOException

Empty response body

Error message

Empty response body

What it means

parseResponse received a 2xx response but response.body() is null, leaving nothing to parse into a HybridResponse. OkHttp returns a null body only in unusual cases (no-content responses, premature stream close, or a misbehaving proxy), so this is treated as a protocol/server defect rather than a content error.

Source

Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/DoclingFastServerClient.java:198

            .url(baseUrl + CONVERT_ENDPOINT)
            .post(bodyBuilder.build())
            .build();
    }

    /**
     * Parses the HTTP response into a HybridResponse.
     */
    private HybridResponse parseResponse(Response response) throws IOException {
        if (!response.isSuccessful()) {
            ResponseBody body = response.body();
            String bodyStr = body != null ? body.string() : "";
            throw new IOException("Docling Fast Server request failed with status " + response.code() +
                ": " + bodyStr);
        }

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

        String responseStr = body.string();
        JsonNode root = objectMapper.readTree(responseStr);

        // Check for API error status
        JsonNode statusNode = root.get("status");
        String status = statusNode != null ? statusNode.asText() : "";
        if ("failure".equals(status)) {
            JsonNode errorsNode = root.get("errors");
            String errorMessage = errorsNode != null ? errorsNode.toString() : "Unknown error";
            throw new IOException("Docling Fast Server processing failed: " + errorMessage);
        }

        // Log partial_success status
        if ("partial_success".equals(status)) {
            JsonNode errorsNode = root.get("errors");
            LOGGER.log(Level.WARNING, "Backend returned partial_success: {0}",

View on GitHub (pinned to a7789b8e77)

Solutions

  1. Bypass any reverse proxy and hit the docling-fast-server directly to confirm it returns a body
  2. Check the server returns 200 (not 204) with a JSON body
  3. Retry the request; transient null bodies are often connection-reuse artifacts
  4. Report to the server operator if it reproduces against the bare server
Defensive patterns

Strategy: try-catch

Try / catch

try {
    return client.convert(request);
} catch (IOException e) {
    if ("Empty response body".equals(e.getMessage())) {
        // likely a proxy stripping the body — retry once against the direct URL
        return client.convert(request);
    }
    throw e;
}

Prevention

When it happens

Trigger: The convert endpoint returns 2xx with a null ResponseBody (e.g. HTTP 204, or a proxy/gateway that strips the body).

Common situations: A reverse proxy/load balancer between client and server that returns 204 or drops the body on large responses; server returning 204 by mistake; keep-alive connection reused after a body was already consumed.

Related errors


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