{"record":{"id":"228d6f9250fcf8f0","repo":"apache/pulsar","slug":"error-preloading-next-range","errorCode":null,"errorMessage":"Error preloading next range","messagePattern":"Error preloading next range","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/LegacyHierarchicalLedgerRangeIterator.java","lineNumber":115,"sourceCode":"    }\n\n    private synchronized void preload() throws IOException {\n        while (nextRange == null && !iteratorDone) {\n            boolean hasMoreElements = false;\n            try {\n                if (l1NodesIter == null) {\n                    List<String> l1Nodes = store.sync(ledgersRoot)\n                            .thenCompose(__ -> store.getChildrenFromStore(ledgersRoot))\n                            .get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);\n                    l1NodesIter = l1Nodes.iterator();\n                    hasMoreElements = nextL1Node();\n                } else if (l2NodesIter == null || !l2NodesIter.hasNext()) {\n                    hasMoreElements = nextL1Node();\n                } else {\n                    hasMoreElements = true;\n                }\n            } catch (ExecutionException | TimeoutException ke) {\n                throw new IOException(\"Error preloading next range\", ke);\n            } catch (InterruptedException ie) {\n                Thread.currentThread().interrupt();\n                throw new IOException(\"Interrupted while preloading\", ie);\n            }\n            if (hasMoreElements) {\n                nextRange = getLedgerRangeByLevel(curL1Nodes, l2NodesIter.next());\n                if (nextRange.size() == 0) {\n                    nextRange = null;\n                }\n            } else {\n                iteratorDone = true;\n            }\n        }\n    }\n\n    @Override\n    public synchronized boolean hasNext() throws IOException {\n        preload();","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/LegacyHierarchicalLedgerRangeIterator.java#L97-L133","documentation":"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.","triggerScenarios":"hasNext() triggers preload(); the store.sync(...).thenCompose(getChildrenFromStore...) future fails or exceeds BLOCKING_CALL_TIMEOUT, surfacing as ExecutionException/TimeoutException.","commonSituations":"Slow or overloaded ZooKeeper/metadata store; network partitions; blocking-call timeout too small for large ledger hierarchies; metadata store session expiry.","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"],"exampleFix":"// before\nLedgerRangeIterator it = lm.getLedgerRanges(...); // throws IOException on slow ZK\n// after\ntry {\n    LedgerRangeIterator it = lm.getLedgerRanges(...);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Error preloading\")) {\n        LOG.warn(\"Metadata store slow/unavailable during ledger enumeration\", e); // retry later\n    }\n    throw e;\n}","handlingStrategy":"retry","validationCode":"// pre-check store health/latency before long enumerations\nstore.getChildrenFromStore(ledgersRoot).orTimeout(5, TimeUnit.SECONDS).join();","typeGuard":null,"tryCatchPattern":"try {\n    while (it.hasNext()) { process(it.next()); }\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Error preloading\")) {\n        // retry after checking metadata-store health; inspect e.getCause()\n    }\n    throw e;\n}","preventionTips":["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"],"tags":["metadata-store","zookeeper","timeout","iteration"],"backgroundTag":"metadata-store-timeout","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"}