{"record":{"id":"27b5d1dfc11c345d","repo":"apache/pulsar","slug":"interrupted-when-connecting-to-zookeeper-server","errorCode":null,"errorMessage":"Interrupted when connecting to zookeeper server","messagePattern":"Interrupted when connecting to zookeeper server","errorType":"console","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/zookeeper/LocalBookkeeperEnsemble.java","lineNumber":558,"sourceCode":"    /* Watching SyncConnected event from ZooKeeper */\n    public static class ZKConnectionWatcher implements Watcher {\n        private final CountDownLatch clientConnectLatch = new CountDownLatch(1);\n\n        @Override\n        public void process(WatchedEvent event) {\n            if (event.getState() == KeeperState.SyncConnected) {\n                clientConnectLatch.countDown();\n            }\n        }\n\n        // Waiting for the SyncConnected event from the ZooKeeper server\n        public void waitForConnection() throws IOException {\n            try {\n                if (!clientConnectLatch.await(zkSessionTimeOut, TimeUnit.MILLISECONDS)) {\n                    throw new IOException(\"Couldn't connect to zookeeper server\");\n                }\n            } catch (InterruptedException e) {\n                throw new IOException(\"Interrupted when connecting to zookeeper server\", e);\n            }\n        }\n    }\n\n    public static boolean waitForServerUp(String hp, long timeout) {\n        long start = System.currentTimeMillis();\n        String[] split = hp.split(\":\");\n        String host = split[0];\n        int port = Integer.parseInt(split[1]);\n        while (true) {\n            try {\n                Socket sock = new Socket(host, port);\n                BufferedReader reader = null;\n                try {\n                    OutputStream outstream = sock.getOutputStream();\n                    outstream.write(\"stat\".getBytes());\n                    outstream.flush();\n","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/zookeeper/LocalBookkeeperEnsemble.java#L540-L576","documentation":"waitForConnection blocks on a ZooKeeper client connect latch up to zkSessionTimeOut milliseconds. If the awaiting thread is interrupted (Thread.interrupt()), the InterruptedException is converted into this IOException with the original interrupt as the cause. It signals the startup/shutdown path was cancelled while waiting for the ZK session to establish, not that the server refused the connection.","triggerScenarios":"LocalBookkeeperEnsemble.initializeZookeper() -> waitForConnection() while zkClient.connect() has not yet completed and another thread interrupts the calling thread (e.g. shutdown hook, future cancellation, service stop).","commonSituations":"Broker/standalone startup aborted during graceful shutdown; a watchdog or test framework timing out and interrupting the bootstrap thread; calling initializeZookeper on a thread pool whose task was cancelled.","solutions":["Investigate who interrupts the thread (enable -Djava.util.concurrent.FastThreadLocal / log at Thread.currentThread().interrupt() sites) and avoid interrupting during ZK bootstrap.","Ensure the ZooKeeper server is up and reachable so the latch counts down quickly and the window for interruption is minimal (waitForServerUp before init).","Increase zkSessionTimeOut if interruption comes from an external timeout racing the connect.","Handle shutdown explicitly: check the interrupt cause and retry initialization on a fresh thread if it was spurious."],"exampleFix":"// before\nensemble.start();\n// after\nThread t = new Thread(() -> {\n    try { ensemble.start(); } catch (IOException e) {\n        if (e.getCause() instanceof InterruptedException) {\n            Thread.currentThread().interrupt(); // preserve status, retry or abort cleanly\n        }\n    }\n});\nt.start();","handlingStrategy":"retry","validationCode":"// before init\nif (!LocalBookkeeperEnsemble.waitForServerUp(zkHost, zkPort, 30000)) {\n    throw new IllegalStateException(\"ZK not up; fix environment before initializing\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    ensemble.start();\n} catch (IOException e) {\n    if (e.getCause() instanceof InterruptedException) {\n        Thread.currentThread().interrupt();\n        // abort startup cleanly or retry once on a non-interrupted thread\n    }\n    throw e;\n}","preventionTips":["Don't interrupt the thread running initializeZookeper; coordinate shutdown via a flag.","Wait for the ZK server with waitForServerUp before initializing.","Size zkSessionTimeOut generously so external watchdogs don't race the connect."],"tags":["zookeeper","interruption","startup","io"],"backgroundTag":"thread-interrupted-during-connect","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}