{"record":{"id":"b067d15de0313791","repo":"apache/pulsar","slug":"bookie-failed-to-start-within-timeout-period","errorCode":null,"errorMessage":"Bookie failed to start within timeout period","messagePattern":"Bookie failed to start within timeout period","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/BKCluster.java","lineNumber":320,"sourceCode":"                org.apache.bookkeeper.server.Main.buildBookieServer(new BookieConfiguration(conf));\n\n        BookieId address = BookieImpl.getBookieId(conf);\n        // Start the bookie directly instead of using ComponentStarter.startComponent()\n        // which registers JVM shutdown hooks that are never cleaned up and can cause\n        // System.exit() during test cleanup, killing the test JVM.\n        server.start();\n\n        // Wait for up to 30 seconds for the bookie to start\n        for (int i = 0; i < 3000; i++) {\n            if (server.lifecycleState() == Lifecycle.State.STARTED) {\n                break;\n            }\n\n            Thread.sleep(10);\n        }\n\n        if (server.lifecycleState() != Lifecycle.State.STARTED) {\n            throw new RuntimeException(\"Bookie failed to start within timeout period\");\n        }\n\n        log.info().attr(\"address\", address).log(\"New bookie has been created\");\n\n        return server;\n    }\n\n    private void startAutoRecovery(BookieServer bserver,\n                                   ServerConfiguration conf) throws Exception {\n        if (isAutoRecoveryEnabled()) {\n            AutoRecoveryMain autoRecoveryProcess = new AutoRecoveryMain(conf);\n            autoRecoveryProcess.start();\n            autoRecoveryProcesses.put(bserver, autoRecoveryProcess);\n            log.debug().attr(\"bookieId\", bserver.getBookieId()).log(\"Starting Auditor Recovery for the bookie\");\n        }\n    }\n\n    private ServerConfiguration newBaseServerConfiguration() {","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/BKCluster.java#L302-L338","documentation":"RuntimeException thrown by BKCluster.startBookie in the test harness when a newly started Bookie server does not reach Lifecycle.State.STARTED within the polling timeout. It indicates the bookie process failed or stalled during startup rather than a client API misuse.","triggerScenarios":"Calling startBookie (via startAllBookies or server) when the bookie throws during startup — bad bookie configuration, port conflicts, disk/journal directories unwritable, or metadata store unreachable — so the polling loop exhausts its timeout while lifecycleState() != STARTED.","commonSituations":"Port already in use in CI; journal/index directories not writable; metadata service not started before the bookie; bookie startup crash hidden in bookie logs.","solutions":["Inspect the bookie server logs for the underlying startup exception (port bind failure, disk errors, metadata connection failures)","Verify the metadata store is running and reachable before starting bookies","Check that bookie journal/ledger directories exist and are writable","Increase the startup wait window or ensure port ranges are free in the test environment"],"exampleFix":"// before\nserver = bkCluster.startBookie(...); // RuntimeException after timeout\n// after\n// free the port / fix dirs first, then:\nawait().atMost(Duration.ofSeconds(30)).until(() -> portIsFree(bookiePort));\nBookieServer server = bkCluster.startBookie(...);","handlingStrategy":"retry","validationCode":"await().atMost(Duration.ofSeconds(30)).until(() -> portIsFree(bookiePort));\n// also verify metadata store is up before starting bookies","typeGuard":null,"tryCatchPattern":"try {\n    BookieServer s = bkCluster.startBookie(...);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"failed to start within timeout\")) {\n        // dump bookie logs, fix env, then restart\n    }\n    throw e;\n}","preventionTips":["Start the metadata service before bookies in test fixtures","Use ephemeral free ports and writable temp journal/ledger dirs","Check bookie logs at the underlying exception — the timeout only masks it"],"tags":["bookkeeper","startup-timeout","test-harness"],"backgroundTag":"service-startup-timeout","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"}