{"record":{"id":"f2ccba8fd7fe5671","repo":"opendataloader-project/opendataloader-pdf","slug":"hancom-ai-server-is-not-available-at-s-check-that","errorCode":null,"errorMessage":"Hancom AI server is not available at %s\nCheck that the server is running and accessible.","messagePattern":"Hancom AI server is not available at (.+?)\nCheck that the server is running and accessible\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/HancomAIClient.java","lineNumber":181,"sourceCode":"    @Override\n    public void checkAvailability() throws IOException {\n        OkHttpClient healthClient = httpClient.newBuilder()\n            .connectTimeout(HEALTH_CHECK_TIMEOUT_MS, TimeUnit.MILLISECONDS)\n            .readTimeout(HEALTH_CHECK_TIMEOUT_MS, TimeUnit.MILLISECONDS)\n            .build();\n\n        Request request = new Request.Builder()\n            .url(baseUrl + PING_ENDPOINT)\n            .get()\n            .build();\n\n        try (Response response = healthClient.newCall(request).execute()) {\n            if (!response.isSuccessful()) {\n                throw new IOException(\"Hancom AI server at \" + baseUrl +\n                    \" returned HTTP \" + response.code());\n            }\n        } catch (IOException e) {\n            throw new IOException(\n                \"Hancom AI server is not available at \" + baseUrl + \"\\n\"\n                + \"Check that the server is running and accessible.\", e);\n        }\n    }\n\n    @Override\n    public HybridResponse convert(HybridRequest request) throws IOException {\n        byte[] pdfBytes = request.getPdfBytes();\n        this.sourcePdfShaShort = sha256ShortHex(pdfBytes);\n        LOGGER.log(Level.INFO, \"Hancom AI: processing PDF ({0} bytes)\", pdfBytes.length);\n\n        // Crop / page-image destination travels with the request, not the\n        // cached client's config, so the per-document target is correct even\n        // when the client is reused across documents (and is concurrency-safe\n        // since nothing shared is mutated).\n        CropOutput cropOutput = request.getCropOutput();\n\n        try (PageImageCache pageImageCache = createPageImageCache()) {","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/opendataloader-project/opendataloader-pdf/blob/a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8/java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/HancomAIClient.java#L163-L199","documentation":"The outer health-check failure for the Hancom AI backend: the catch at line 180 wraps any IOException from the /ping call (both connection failures and the non-2xx case from error 50) into a single 'not available' message with the original as cause. It means the client could not confirm the backend is healthy and will not proceed with the Hancom pipeline.","triggerScenarios":"healthClient.newCall(request).execute() throws IOException (connection refused/timeout/DNS) OR the inner throw at line 177 (non-2xx /ping) propagates into this catch.","commonSituations":"Hancom AI server not started; wrong host/port (default 18008); firewall/network isolation; server crashed or still booting; /ping returning non-2xx on this server build.","solutions":["Start the Hancom AI server and confirm it is listening on the configured port (default 18008)","Set the correct address via --hybrid-url http://host:port","Verify with curl http://host:18008/ping that it returns 2xx","Inspect getCause() to distinguish connection-refused from a non-2xx /ping","Use --hybrid-fallback or run without --hybrid for Java-only output"],"exampleFix":"// before\nopendataloader-pdf --hybrid=hancom-ai in.pdf\n// after\nopendataloader-pdf --hybrid=hancom-ai --hybrid-fallback in.pdf","handlingStrategy":"fallback","validationCode":"// Probe the Hancom AI server before running\ntry (java.net.Socket s = new java.net.Socket()) {\n    s.connect(new InetSocketAddress(host, 18008), 1000);\n} catch (IOException e) {\n    config.setHybrid(null); // Java-only\n}","typeGuard":null,"tryCatchPattern":"try {\n    client.checkAvailability();\n} catch (IOException e) {\n    Throwable cause = e.getCause(); // distinguishes conn-refused vs non-2xx /ping\n    log.warn(\"Hancom AI unavailable: {}\", e.getMessage());\n    config.getHybridConfig().setFallbackToJava(true);\n}","preventionTips":["Run the Hancom AI server under a process supervisor that auto-restarts","Verify curl http://host:18008/ping returns 2xx before submitting jobs","Pass --hybrid-fallback in automated pipelines"],"tags":["network","hybrid","hancom-ai","connection","health-check"],"backgroundTag":null,"analyzedSha":"a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8","analyzedAt":"2026-08-14T05:22:03.953Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}