opendataloader-project/opendataloader-pdf · critical · IOException
Hybrid server is not available at %s Please check the server
Error message
Hybrid server is not available at %s Please check the server URL and ensure the Hancom API is accessible. Or pass --hybrid-fallback to fall back to Java-only output for this run. Or run without --hybrid flag for Java-only processing.
What it means
HancomClient.checkAvailability() sends a HEAD request to the base URL and any IOException (connection refused, DNS resolution failure, connect timeout, SSL handshake error) is caught and re-thrown with actionable guidance. A successful HTTP response of any status code (including 401/403) proves connectivity because the Hancom API requires authentication on all endpoints. This error means the server is entirely unreachable, not merely returning an error code.
Source
Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/hybrid/HancomClient.java:121
@Override
public void checkAvailability() throws IOException {
OkHttpClient healthClient = httpClient.newBuilder()
.connectTimeout(HEALTH_CHECK_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.readTimeout(HEALTH_CHECK_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.build();
Request request = new Request.Builder()
.url(baseUrl)
.head()
.build();
try (Response response = healthClient.newCall(request).execute()) {
// Any HTTP response (including 4xx/5xx) means the server is reachable.
// Hancom API requires authentication for all endpoints, so a 401/403
// is expected and still proves connectivity.
} catch (IOException e) {
throw new IOException(
"Hybrid server is not available at " + baseUrl + "\n"
+ "Please check the server URL and ensure the Hancom API is accessible.\n"
+ "Or pass --hybrid-fallback to fall back to Java-only output for this run.\n"
+ "Or run without --hybrid flag for Java-only processing.", e);
}
}
@Override
public HybridResponse convert(HybridRequest request) throws IOException {
String fileId = null;
try {
// Step 1: Upload PDF
fileId = uploadFile(request.getPdfBytes());
LOGGER.log(Level.FINE, "Uploaded file with ID: {0}", fileId);
// Step 2: Get visual info
JsonNode visualInfo = getVisualInfo(fileId);
LOGGER.log(Level.FINE, "Retrieved visual info for file: {0}", fileId);View on GitHub (pinned to a7789b8e77)
Solutions
- Verify the server URL with curl: `curl -I <url>` or `curl -sS -o /dev/null -w '%{http_code}' <url>` — any HTTP status code (even 401) confirms reachability.
- Pass --hybrid-fallback to continue processing with Java-only output for this run while the server issue is investigated.
- Drop the --hybrid flag entirely to run in pure Java mode without any availability check.
- Check DNS resolution: `nslookup <hostname>` or `dig <hostname>` to rule out DNS failures.
- If using a self-hosted Hancom instance, confirm the service is running and the port is open: `telnet <host> <port>` or `nc -zv <host> <port>`.
- For HTTPS endpoints, verify certificate validity with `openssl s_client -connect <host>:443`.
Example fix
// before: throws and aborts the whole run
client.checkAvailability();
// after: graceful fallback to Java-only processing
try {
client.checkAvailability();
} catch (IOException e) {
if (config.isFallbackToJava()) {
LOGGER.warning("Hybrid server unavailable, falling back to Java-only: " + e.getMessage());
// proceed with Java-only pipeline
} else {
throw e;
}
} Defensive patterns
Strategy: fallback
Validate before calling
// Validate reachability before starting hybrid processing
try {
client.checkAvailability();
} catch (IOException e) {
if (config.isFallbackToJava()) {
LOGGER.warning("Hybrid unavailable, using Java-only mode");
runJavaOnlyPipeline();
return;
}
throw e;
} Try / catch
try {
client.checkAvailability();
} catch (IOException e) {
// The error message already suggests --hybrid-fallback and removing --hybrid
if (config.isFallbackToJava()) {
proceedWithJavaOnly();
} else {
// Re-throw — the user must decide whether to fall back
throw e;
}
} Prevention
- Always set --hybrid-fallback when running in production to avoid hard failures on network issues.
- Use a health-check wrapper that retries checkAvailability with a short delay before giving up.
- Configure OkHttp connectTimeout to fail fast rather than hanging on unreachable hosts.
- Keep the server URL in a centralized config to avoid typos across deployments.
When it happens
Trigger: Calling HybridClient.checkAvailability() on a HancomClient when the server URL is wrong, the host is down, a firewall blocks the port, DNS cannot resolve the hostname, or the HEALTH_CHECK_TIMEOUT_MS window expires before the TCP connection establishes. Also triggered when an HTTPS URL is used but the server certificate is invalid or the TLS version is unsupported.
Common situations: Wrong --hybrid-url (typo, missing port, forgot /api path suffix); server not started yet; corporate VPN or firewall blocking outbound access to dataloader.cloud.hancom.com; using http:// against an HTTPS-only endpoint; DNS outage or stale cached entry pointing to a decommissioned IP.
Related errors
- Hancom upload failed with status %s: %s
- Empty response body from upload
- Hancom visualinfo failed with status %s: %s
- Empty response body from visualinfo
- Unsupported hybrid backend '%s'. Supported values: %s
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/1469398372b95362.
Report an issue: GitHub.