apache/pulsar · error · IOException
IOException
Error message
IOException
What it means
getChildrenAt() lists the children of a metadata-store path used for hierarchical ledger enumeration. It converts async metadata-store failures (execution errors, timeouts, or thread interruption) into a plain IOException because the BookKeeper iterator API is synchronous. Thrown when the store.sync/getChildrenFromStore future fails or does not complete within BLOCKING_CALL_TIMEOUT.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/LongHierarchicalLedgerRangeIterator.java:66
}
/**
* Returns all children with path as a parent. If path is non-existent,
* returns an empty list anyway (after all, there are no children there).
* Maps all exceptions (other than NoNode) to IOException in keeping with
* LedgerRangeIterator.
*
* @param path
* @return Iterator into set of all children with path as a parent
* @throws IOException
*/
List<String> getChildrenAt(String path) throws IOException {
try {
return store.sync(path).thenCompose(__ -> store.getChildrenFromStore(path))
.get(AbstractMetadataDriver.BLOCKING_CALL_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (ExecutionException | TimeoutException e) {
log.debug().attr("path", path).log("Failed to get children");
throw new IOException(e);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new IOException("Interrupted while reading ledgers at path " + path, ie);
}
}
/**
* Represents the ledger range rooted at a leaf node, returns at most one LedgerRange.
*/
class LeafIterator implements LedgerManager.LedgerRangeIterator {
// Null iff iteration is complete
LedgerManager.LedgerRange range;
LeafIterator(String path) throws IOException {
List<String> ledgerLeafNodes = getChildrenAt(path);
Set<Long> ledgerIds = HierarchicalLedgerUtils.ledgerListToSet(ledgerLeafNodes, ledgerRootPath, path);
log.debug().attr("hashNode", path)
.attr("ledgers", ledgerIds)View on GitHub (pinned to 820761864e)
Solutions
- Check metadata store connectivity and health (ZooKeeper ensemble or service URL).
- Increase BLOCKING_CALL_TIMEOUT if the store is slow, or reduce store load.
- Inspect the cause via IOException#getCause for the underlying store error.
- Retry iteration after the store recovers; re-create the iterator at the last successful ledger id.
Example fix
// before
try { while (it.hasMoreElements()) { it.nextElement(); } }
catch (IOException e) { log.error("ledger range listing failed", e); }
// after
try { while (it.hasMoreElements()) { it.nextElement(); } }
catch (IOException e) {
if (e.getCause() instanceof TimeoutException) {
log.warn("metadata store timed out; retrying", e); // retry with backoff
} else { throw e; }
} Defensive patterns
Strategy: try-catch
Validate before calling
// check store reachability before iterating store.sync(ledgersRootPath).get(30, TimeUnit.SECONDS);
Try / catch
try { ... } catch (IOException e) {
Throwable cause = e.getCause();
if (cause instanceof TimeoutException) { /* retry/backoff */ }
else if (Thread.currentThread().isInterrupted()) { return; }
else { throw e; }
} Prevention
- Monitor metadata store health before starting ledger scans
- Run iteration on threads that are not interrupted at shutdown
- Use timeouts generous relative to store latency
- Recreate the iterator after transient failures
When it happens
Trigger: Calling LongHierarchicalLedgerRangeIterator iteration (hasMoreElements/next) that invokes getChildrenAt(path) when the metadata store is down/unreachable, the path cannot be read, or the call exceeds AbstractMetadataDriver.BLOCKING_CALL_TIMEOUT.
Common situations: ZooKeeper/etcd outages during ledger listing; slow or overloaded metadata store causing timeouts; interrupted threads during broker shutdown; missing/incorrect ledger metadata root path configuration.
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/f0107d0fe3ddb5e1.
Report an issue: GitHub.