apache/pulsar · error · IOException
it is not a valid hashed path name : ${ledgerPath}
Error message
it is not a valid hashed path name : ${ledgerPath} What it means
PulsarLedgerManager.getLedgerId converts a metadata-store znode path back into a BookKeeper ledger id. If the given path does not start with the configured ledgerRootPath, it cannot be a ledger znode managed by this ledger manager, so an IOException is thrown naming the offending path.
Source
Thrown at pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarLedgerManager.java:377
@Override
public void close() throws IOException {
scheduler.shutdownNow();
try {
scheduler.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new IOException(ie);
}
}
public String getLedgerPath(long ledgerId) {
return this.ledgerRootPath + StringUtils.getHybridHierarchicalLedgerPath(ledgerId);
}
private long getLedgerId(String ledgerPath) throws IOException {
if (!ledgerPath.startsWith(ledgerRootPath)) {
throw new IOException("it is not a valid hashed path name : " + ledgerPath);
}
String hierarchicalPath = ledgerPath.substring(ledgerRootPath.length() + 1);
return StringUtils.stringToLongHierarchicalLedgerId(hierarchicalPath);
}
/**
* ReadLedgerMetadataTask class.
*/
private class ReadLedgerMetadataTask implements Runnable {
final long ledgerId;
ReadLedgerMetadataTask(long ledgerId) {
this.ledgerId = ledgerId;
}
@OverrideView on GitHub (pinned to 820761864e)
Solutions
- Verify the ledgerRootPath in the broker/bookkeeper configuration matches the actual path where ledger znodes live in the metadata store.
- Check the path in the error message: if it legitimately lives elsewhere, do not pass it to this ledger manager's getLedgerId/deserialize.
- If paths were migrated, rewrite or re-create the ledger hierarchy under the configured root (e.g. with BookKeeper shell) instead of pointing config at the old data.
- Inspect who produced the path (handleDataNotification watch vs deserialize of stored data) and filter out nodes not under the ledgers root before parsing.
Example fix
// before
long ledgerId = ledgerManager.getLedgerId(notificationPath);
// after
if (notificationPath.startsWith(conf.getLedgerRootPath())) {
long ledgerId = ledgerManager.getLedgerId(notificationPath);
} else {
log.warn("Ignoring notification for foreign path {}", notificationPath);
} Defensive patterns
Strategy: validation
Validate before calling
if (path != null && path.startsWith(ledgerRootPath + "/")) {
long ledgerId = ledgerManager.getLedgerId(path);
} Try / catch
try {
long ledgerId = ledgerManager.getLedgerId(path);
} catch (IOException e) {
log.warn("Not a ledger path: {}", path); // skip foreign notifications
} Prevention
- Keep ledgerRootPath configuration identical across all brokers and bookies.
- Filter metadata-watch notifications to paths under the configured ledgers root before parsing.
- After any ledgers root migration, re-verify stored paths match the new config.
When it happens
Trigger: Calling getLedgerId (via deserialize or handleDataNotification) with a path from outside the ledgers root, e.g. a path whose prefix differs from the configured ledgerRootPath (typo, trailing slash mismatch, or a notification for a node not under the ledgers hierarchy).
Common situations: Misconfigured metadataServiceUri / ledgersRootPath that changed after ledgers were created; metadata-watch notifications firing for unrelated znodes; manually moving or copying ledgers data under a different root; running multiple BookKeeper clusters against one metadata store.
Related errors
- rereplicationEntryBatchSize should be smaller than maxPendin
- Metadata store address argument is required (--metadata-stor
- is not an instance of MetadataStore
- Neither METADATA_STORE_INSTANCE configuration set in the BK
- METADATA_SERVICE_ERROR
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/9f47c5476d51d61e.
Report an issue: GitHub.