# Connection Error (/sdks/java/how-to/error-handling/connection-error)



## Overview [#overview]

A network partition, a server that hasn't started yet, or a typo in the address are all normal facts of life in distributed systems — and a client that blocks indefinitely or crashes with an unhandled exception turns a routine outage into a cascading failure. **Fail-fast connection checking** lets you detect an unreachable KubeMQ server explicitly, rather than discovering it deep inside unrelated business logic, so your service can log the failure, alert, or fall back instead of hanging.

`PubSubClient.builder().build()` creates the gRPC channel eagerly but defers the TCP connection until the first RPC — calling `ping()` right after construction forces that connection and surfaces `KubeMQException` immediately if the server is unreachable. `QueueSendResult.isError()` and `QueuesPollResponse.isError()` catch a different failure class: application-level errors the broker returns over a successful transport, distinct from a thrown exception. &#x2A;*Gotchas:** `build()` succeeding tells you nothing about reachability — always `ping()` before relying on the connection; checking `isError()` is not optional, since a failed send or receive doesn't throw, it just returns a flagged result; unacknowledged messages from `receiveQueueMessages` are redelivered after the visibility timeout, so a crash between receive and `ack()` is expected, not a bug.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Java SDK installed (`implementation 'io.kubemq.sdk:kubemq-sdk-Java:3.1.1'` (Gradle) or Maven dependency from [Getting Started](/sdks/java))

## Code [#code]

```java title="ConnectionErrorExample.java"
package io.kubemq.example.errorhandling;

import io.kubemq.sdk.common.ServerInfo;
import io.kubemq.sdk.pubsub.PubSubClient;
import io.kubemq.sdk.queues.*;

/**
 * Connection Error Example
 *
 * Demonstrates handling connection errors when working with KubeMQ.
 */
public class ConnectionErrorExample {

    private static final String ADDRESS = "localhost:50000";
    private static final String CLIENT_ID = "java-errorhandling-connection-error-client";

    public static void main(String[] args) {
        System.out.println("=== Connection Error Handling ===\n");

        // Test 1: Connection to invalid address (expect failure)
        System.out.println("1. Attempting connection to wrong address...");
        try {
            PubSubClient badClient = PubSubClient.builder()
                    .address("localhost:99999").clientId(CLIENT_ID).build();
            badClient.ping();
            badClient.close();
        } catch (Exception e) {
            System.out.println("   Failed (expected): " + e.getClass().getSimpleName());
        }

        // Test 2: Connection to valid address (expect success)
        System.out.println("\n2. Attempting connection to valid address...");
        try {
            PubSubClient goodClient = PubSubClient.builder()
                    .address(ADDRESS).clientId(CLIENT_ID).build();
            ServerInfo info = goodClient.ping();
            System.out.println("   Connected: " + info.getHost() + " v" + info.getVersion());
            goodClient.close();
        } catch (Exception e) {
            System.out.println("   Failed: " + e.getMessage());
        }

        // Test 3: Queue operations with error checking
        System.out.println("\n3. Queue operation error handling...");
        try (QueuesClient client = QueuesClient.builder().address(ADDRESS).clientId(CLIENT_ID).build()) {
            client.ping();
            String testQueue = "java-errorhandling.error-test";
            client.createQueuesChannel(testQueue);

            QueueSendResult result = client.sendQueueMessage(QueueMessage.builder()
                    .channel(testQueue).body("Test".getBytes()).build());
            System.out.println("   Send error: " + result.isError());

            QueuesPollResponse response = client.receiveQueueMessages(QueuesPollRequest.builder()
                    .channel(testQueue).pollMaxMessages(10).pollWaitTimeoutInSeconds(2).build());
            System.out.println("   Receive error: " + response.isError());
            response.getMessages().forEach(QueueMessageReceived::ack);

            client.deleteQueuesChannel(testQueue);
        } catch (Exception e) {
            System.out.println("   Error: " + e.getMessage());
        }

        System.out.println("\nConnection error examples completed.");
    }
}

```

## How It Works [#how-it-works]

* Connecting to an invalid address (`localhost:99999`) fails on the first RPC (`ping()`), not at `build()` — the gRPC channel is created eagerly but the actual TCP connection is deferred until first use.
* `KubeMQException` (and its subclasses) are unchecked; wrap operations in `try/catch` at the level where you can meaningfully handle or log the failure.
* `QueueSendResult.isError()` and `QueuesPollResponse.isError()` let you check application-level errors returned by the broker after a successful transport — these are separate from transport exceptions.
* `QueueMessageReceived::ack` is called as a method reference to acknowledge each message individually; unacknowledged messages are redelivered after the visibility timeout.

## Related [#related]

* [Java SDK Reference](/sdks/java/reference)
* [Graceful Shutdown](/sdks/java/how-to/error-handling/graceful-shutdown)
* [Reconnection](/sdks/java/how-to/error-handling/reconnection)
