apache/pulsar · error · IOException
IOException
Error message
IOException
What it means
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.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLayoutManager.java:62
private final String layoutPath;
public PulsarLayoutManager(MetadataStoreExtended store, String ledgersRootPath) {
this.ledgersRootPath = ledgersRootPath;
this.store = store;
this.layoutPath = ledgersRootPath + "/" + BookKeeperConstants.LAYOUT_ZNODE;
}
@Override
public LedgerLayout readLedgerLayout() throws IOException {
try {
byte[] layoutData = store.get(layoutPath).get(BLOCKING_CALL_TIMEOUT, MILLISECONDS)
.orElseThrow(() -> new BookieException.MetadataStoreException("Layout node not found"))
.getValue();
return LedgerLayout.parseLayout(layoutData);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException(e);
} catch (BookieException | ExecutionException | TimeoutException e) {
throw new IOException(e);
}
}
@Override
public void storeLedgerLayout(LedgerLayout ledgerLayout) throws IOException {
try {
byte[] layoutData = ledgerLayout.serialize();
store.put(layoutPath, layoutData, Optional.of(-1L))
.get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException(e);
} catch (TimeoutException e) {
throw new IOException(e);
} catch (ExecutionException e) {View on GitHub (pinned to 820761864e)
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.
Example fix
// before
LedgerLayout layout = layoutManager.readLedgerLayout(); // fails on fresh cluster
// after
byte[] data = store.get(layoutPath).get();
if (data.isEmpty()) {
layoutManager.storeLedgerLayout(LedgerLayout.of(...)); // bootstrap layout first
}
LedgerLayout layout = layoutManager.readLedgerLayout(); Defensive patterns
Strategy: try-catch
Validate before calling
// verify layout node exists before reading boolean exists = store.exists(layoutPath).get(30, TimeUnit.SECONDS);
Try / catch
try { layout = mgr.readLedgerLayout(); }
catch (IOException e) {
Throwable c = e.getCause();
if (c instanceof BookieException.MetadataStoreException) { /* bootstrap layout or fix path */ }
else if (c instanceof TimeoutException) { /* retry */ }
else throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Fresh clusters before any layout was written; misconfigured ledgersRootPath pointing to the wrong znode prefix; metadata store outages during bookie/broker startup; interrupted shutdown.
Related errors
- IOException
- Error contacting with metadata store
- Failed to acuire under-replicated ledger
- Cursor %s mark-delete position %s is ahead of the last posit
- Timeout during managed ledger close
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/7165f85840b973dd.
Report an issue: GitHub.