{"record":{"id":"7165f85840b973dd","repo":"apache/pulsar","slug":"ioexception-7165f8","errorCode":null,"errorMessage":"IOException","messagePattern":"IOException","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLayoutManager.java","lineNumber":62,"sourceCode":"\n    private final String layoutPath;\n\n    public PulsarLayoutManager(MetadataStoreExtended store, String ledgersRootPath) {\n        this.ledgersRootPath = ledgersRootPath;\n        this.store = store;\n        this.layoutPath = ledgersRootPath + \"/\" + BookKeeperConstants.LAYOUT_ZNODE;\n    }\n\n    @Override\n    public LedgerLayout readLedgerLayout() throws IOException {\n        try {\n            byte[] layoutData = store.get(layoutPath).get(BLOCKING_CALL_TIMEOUT, MILLISECONDS)\n                    .orElseThrow(() -> new BookieException.MetadataStoreException(\"Layout node not found\"))\n                    .getValue();\n            return LedgerLayout.parseLayout(layoutData);\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new IOException(e);\n        } catch (BookieException | ExecutionException | TimeoutException e) {\n            throw new IOException(e);\n        }\n    }\n\n    @Override\n    public void storeLedgerLayout(LedgerLayout ledgerLayout) throws IOException {\n        try {\n            byte[] layoutData = ledgerLayout.serialize();\n\n            store.put(layoutPath, layoutData, Optional.of(-1L))\n                    .get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new IOException(e);\n        } catch (TimeoutException e) {\n            throw new IOException(e);\n        } catch (ExecutionException e) {","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLayoutManager.java#L44-L80","documentation":"PulsarLayoutManager.readLedgerLayout() reads the LedgerLayout node from the metadata store and blocks on the future. Any metadata store failure (BookieException.MetadataStoreException 'Layout node not found', ExecutionException, TimeoutException) or interruption is wrapped in an IOException because the BookKeeperLayoutManager API is synchronous.Thrown when layout data cannot be retrieved within BLOCKING_CALL_TIMEOUT.","triggerScenarios":"Calling readLedgerLayout() when the layout node (e.g. /ledgers/LAYOUT) does not exist, the metadata store is unreachable, the read times out, or the thread is interrupted.","commonSituations":"Fresh clusters before any layout was written; misconfigured ledgersRootPath pointing to the wrong znode prefix; metadata store outages during bookie/broker startup; interrupted shutdown.","solutions":["Check that the ledgers root path and layout node exist in the metadata store; write the layout (storeLedgerLayout) if bootstrapping.","Verify metadataStoreUrl configuration matches the cluster's actual store layout.","Check metadata store health and increase timeout if reads are slow.","Inspect IOException#getCause for the concrete BookieException/TimeoutException."],"exampleFix":"// before\nLedgerLayout layout = layoutManager.readLedgerLayout(); // fails on fresh cluster\n// after\nbyte[] data = store.get(layoutPath).get();\nif (data.isEmpty()) {\n    layoutManager.storeLedgerLayout(LedgerLayout.of(...)); // bootstrap layout first\n}\nLedgerLayout layout = layoutManager.readLedgerLayout();","handlingStrategy":"try-catch","validationCode":"// verify layout node exists before reading\nboolean exists = store.exists(layoutPath).get(30, TimeUnit.SECONDS);","typeGuard":null,"tryCatchPattern":"try { layout = mgr.readLedgerLayout(); }\ncatch (IOException e) {\n  Throwable c = e.getCause();\n  if (c instanceof BookieException.MetadataStoreException) { /* bootstrap layout or fix path */ }\n  else if (c instanceof TimeoutException) { /* retry */ }\n  else throw e;\n}","preventionTips":["Verify ledgersRootPath matches the cluster's store layout","Bootstrap layout before first read on fresh clusters","Monitor metadata store availability","Increase timeout for high-latency stores"],"tags":["io","metadata-store","bookkeeper","layout","timeout"],"backgroundTag":"metadata-store-unavailable","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}