{"record":{"id":"2dad090aa7ad4c8f","repo":"opendataloader-project/opendataloader-pdf","slug":"hybrid-server-at-s-returned-http-s-during-health","errorCode":null,"errorMessage":"Hybrid server at %s returned HTTP %s during health check.\nThe server is reachable but may be starting up or unhealthy.","messagePattern":"Hybrid server at (.+?) returned HTTP (.+?) during health check\\.\nThe server is reachable but may be starting up or unhealthy\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/DoclingFastServerClient.java","lineNumber":125,"sourceCode":"            .get()\n            .build();\n\n        Response response;\n        try {\n            response = healthClient.newCall(healthRequest).execute();\n        } catch (IOException e) {\n            throw new IOException(\n                \"Hybrid server is not available at \" + baseUrl + \"\\n\"\n                + \"To start the local hybrid server:\\n\"\n                + \"  1. Install: pip install \\\"opendataloader-pdf[hybrid]\\\"\\n\"\n                + \"  2. Start:   opendataloader-pdf-hybrid --port 5002\\n\"\n                + \"To use a remote server or custom port: --hybrid-url http://host:port\\n\"\n                + \"Or pass --hybrid-fallback to fall back to Java-only output for this run.\\n\"\n                + \"Or run without --hybrid flag for Java-only processing.\", e);\n        }\n        try (response) {\n            if (!response.isSuccessful()) {\n                throw new IOException(\n                    \"Hybrid server at \" + baseUrl + \" returned HTTP \" + response.code()\n                    + \" during health check.\\n\"\n                    + \"The server is reachable but may be starting up or unhealthy.\");\n            }\n        }\n    }\n\n    @Override\n    public HybridResponse convert(HybridRequest request) throws IOException {\n        Request httpRequest = buildConvertRequest(request);\n        LOGGER.log(Level.FINE, \"Sending request to {0}\", baseUrl + CONVERT_ENDPOINT);\n\n        try (Response response = httpClient.newCall(httpRequest).execute()) {\n            return parseResponse(response);\n        }\n    }\n\n    @Override","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/opendataloader-project/opendataloader-pdf/blob/a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8/java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/DoclingFastServerClient.java#L107-L143","documentation":"The docling-fast-server health check connected and got an HTTP response, but the status code was not 2xx. This distinguishes 'unreachable' (error 43) from 'reachable but unhealthy'. The message notes the server may be starting up or in a bad state, since a running process that fails /health typically is mid-initialization or has crashed its worker.","triggerScenarios":"GET to baseUrl + '/health' succeeds at the TCP/HTTP level but returns a non-2xx status (e.g. 500 or 503) within the 3s health-check timeout.","commonSituations":"Server still loading the ML model on first request (returns 503); backend crashed but the FastAPI/liveness wrapper still answers; version mismatch between client expectations and server /health contract; resource exhaustion (OOM) making the server return 500.","solutions":["Wait for the server to finish model warm-up and retry","Check the server logs for startup errors or OOM","Upgrade/downgrade the server to a version whose /health returns 200 when ready","Use --hybrid-fallback or drop --hybrid to proceed Java-only"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Retry the health check while the server warms up\nfor (int attempt = 1; attempt <= 5; attempt++) {\n    try {\n        client.checkAvailability();\n        break;\n    } catch (IOException e) {\n        if (attempt == 5 || !e.getMessage().contains(\"during health check\")) throw e;\n        Thread.sleep(2000L * attempt);\n    }}","preventionTips":["Add a readiness wait loop after starting the server (it returns non-2xx while loading models)","Monitor server /health in your orchestrator and only route traffic when 200","Keep model warm-up off the critical path of the first document"],"tags":["network","hybrid","docling-fast","health-check","http-status"],"backgroundTag":null,"analyzedSha":"a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8","analyzedAt":"2026-08-14T05:22:03.953Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}