apache/pulsar · error · IOException
Error preloading next range
Error message
Error preloading next range
What it means
IOException 'Error preloading next range' thrown by LegacyHierarchicalLedgerRangeIterator.preload when the blocking future that fetches the next ledger range from the metadata store completes with ExecutionException or times out (TimeoutException). It signals a failure or slowness of the underlying metadata store while enumerating ledger hierarchy nodes.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/LegacyHierarchicalLedgerRangeIterator.java:115
}
private synchronized void preload() throws IOException {
while (nextRange == null && !iteratorDone) {
boolean hasMoreElements = false;
try {
if (l1NodesIter == null) {
List<String> l1Nodes = store.sync(ledgersRoot)
.thenCompose(__ -> store.getChildrenFromStore(ledgersRoot))
.get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);
l1NodesIter = l1Nodes.iterator();
hasMoreElements = nextL1Node();
} else if (l2NodesIter == null || !l2NodesIter.hasNext()) {
hasMoreElements = nextL1Node();
} else {
hasMoreElements = true;
}
} catch (ExecutionException | TimeoutException ke) {
throw new IOException("Error preloading next range", ke);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new IOException("Interrupted while preloading", ie);
}
if (hasMoreElements) {
nextRange = getLedgerRangeByLevel(curL1Nodes, l2NodesIter.next());
if (nextRange.size() == 0) {
nextRange = null;
}
} else {
iteratorDone = true;
}
}
}
@Override
public synchronized boolean hasNext() throws IOException {
preload();View on GitHub (pinned to 820761864e)
Solutions
- Check metadata-store health, latency, and network connectivity between client and store
- Increase the BLOCKING_CALL_TIMEOUT if the hierarchy is large and calls legitimately exceed it
- Retry the iteration after the metadata store recovers; inspect the wrapped cause (ke.getCause()) for the root error
Example fix
// before
LedgerRangeIterator it = lm.getLedgerRanges(...); // throws IOException on slow ZK
// after
try {
LedgerRangeIterator it = lm.getLedgerRanges(...);
} catch (IOException e) {
if (e.getMessage().startsWith("Error preloading")) {
LOG.warn("Metadata store slow/unavailable during ledger enumeration", e); // retry later
}
throw e;
} Defensive patterns
Strategy: retry
Validate before calling
// pre-check store health/latency before long enumerations store.getChildrenFromStore(ledgersRoot).orTimeout(5, TimeUnit.SECONDS).join();
Try / catch
try {
while (it.hasNext()) { process(it.next()); }
} catch (IOException e) {
if (e.getMessage().startsWith("Error preloading")) {
// retry after checking metadata-store health; inspect e.getCause()
}
throw e;
} Prevention
- Monitor metadata-store latency; scale ZK before enumerations time out
- Keep BLOCKING_CALL_TIMEOUT sized to the largest expected hierarchy
- Avoid enumerating the full hierarchy during metadata-store incidents
When it happens
Trigger: hasNext() triggers preload(); the store.sync(...).thenCompose(getChildrenFromStore...) future fails or exceeds BLOCKING_CALL_TIMEOUT, surfacing as ExecutionException/TimeoutException.
Common situations: Slow or overloaded ZooKeeper/metadata store; network partitions; blocking-call timeout too small for large ledger hierarchies; metadata store session expiry.
Related errors
- Failed to get children of ${path}
- Failed to check exist ${POLICIES_READONLY_FLAG_PATH}
- Error when get child nodes from zk
- Error contacting with metadata store
- Error reading list
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/228d6f9250fcf8f0.
Report an issue: GitHub.