opendataloader-project/opendataloader-pdf · error · IOException

Docling Fast Server request failed with status %s: %s

Error message

Docling Fast Server request failed with status %s: %s

What it means

After posting the PDF to /v1/convert/file, parseResponse checks response.isSuccessful(). A non-2xx status means the server rejected the conversion request itself; the response body (if any) is appended so the caller sees the server's error text. This is distinct from a 2xx that later reports status:'failure' (error 48).

Source

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

            int minPage = request.getPageNumbers().stream().min(Integer::compareTo).orElse(1);
            int maxPage = request.getPageNumbers().stream().max(Integer::compareTo).orElse(Integer.MAX_VALUE);
            bodyBuilder.addFormDataPart("page_ranges", minPage + "-" + maxPage);
        }

        return new Request.Builder()
            .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);

View on GitHub (pinned to a7789b8e77)

Solutions

  1. Read the body fragment in the message to see the server's reason
  2. Retry on 5xx with backoff for transient server faults
  3. Reduce the page range (request.getPageNumbers()) to shrink the payload
  4. Check server version matches the client's expected /v1/convert/file contract
  5. Fall back to Java-only via --hybrid-fallback if the server is unreliable
Defensive patterns

Strategy: try-catch

Try / catch

try {
    HybridResponse r = client.convert(request);
} catch (IOException e) {
    if (e.getMessage().startsWith("Docling Fast Server request failed with status")) {
        String body = e.getMessage(); // contains the server error text
        log.error("convert rejected by server: {}", body);
    }
    throw e;
}

Prevention

When it happens

Trigger: POST to baseUrl + '/v1/convert/file' returns a non-2xx HTTP code; body string (or empty string) is concatenated into the message.

Common situations: Malformed multipart payload; server-side timeout during conversion (504); payload too large (413); server bug returning 500; wrong endpoint/contract due to version mismatch.

Related errors


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