{"record":{"id":"3de646f9a235f863","repo":"apache/pulsar","slug":"it-is-not-a-valid-hashed-path-name-pathname","errorCode":null,"errorMessage":"it is not a valid hashed path name : ${pathName}","messagePattern":"it is not a valid hashed path name : (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/LongHierarchicalLedgerManager.java","lineNumber":38,"sourceCode":"\nimport java.io.IOException;\nimport java.util.concurrent.ScheduledExecutorService;\nimport lombok.CustomLog;\nimport org.apache.bookkeeper.proto.BookkeeperInternalCallbacks;\nimport org.apache.bookkeeper.util.StringUtils;\nimport org.apache.pulsar.metadata.api.MetadataStore;\nimport org.apache.zookeeper.AsyncCallback;\n\n@CustomLog\nclass LongHierarchicalLedgerManager extends AbstractHierarchicalLedgerManager {\n    public LongHierarchicalLedgerManager(MetadataStore store, ScheduledExecutorService scheduler,\n                                         String ledgerRootPath) {\n        super(store, scheduler, ledgerRootPath);\n    }\n\n    public long getLedgerId(String pathName) throws IOException {\n        if (!pathName.startsWith(ledgerRootPath)) {\n            throw new IOException(\"it is not a valid hashed path name : \" + pathName);\n        }\n        String hierarchicalPath = pathName.substring(ledgerRootPath.length() + 1);\n        return StringUtils.stringToLongHierarchicalLedgerId(hierarchicalPath);\n    }\n\n    public String getLedgerPath(long ledgerId) {\n        return ledgerRootPath + StringUtils.getLongHierarchicalLedgerPath(ledgerId);\n    }\n\n    //\n    // Active Ledger Manager\n    //\n\n    public void asyncProcessLedgers(final BookkeeperInternalCallbacks.Processor<Long> processor,\n                                    final AsyncCallback.VoidCallback finalCb,\n                                    final Object context, final int successRc, final int failureRc) {\n\n        // If it succeeds, proceed with our own recursive ledger processing for the 63-bit id ledgers","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/LongHierarchicalLedgerManager.java#L20-L56","documentation":"IOException thrown by LongHierarchicalLedgerManager.getLedgerId when the given path does not start with the configured ledgerRootPath, meaning it is not a valid long-hierarchical hashed ledger path and cannot be converted back to a ledger id.","triggerScenarios":"Calling getLedgerId with a path produced by a different ledger manager layout, a path missing the ledger root prefix, or after the ledgerRootPath config changed between runs so stored/returned paths no longer match the prefix.","commonSituations":"Mixing HierarchicalLedgerManager and LongHierarchicalLedgerManager layouts; migrating ledger manager types without updating the layout; typo/mismatch in ledgerRootPath configuration; calling getLedgerId on the root path itself or a non-ledger node.","solutions":["Pass only paths returned by getLedgerPath for this manager (with the exact ledgerRootPath prefix)","Verify the ledgerRootPath configuration matches the layout used to create the ledger paths","Confirm the correct ledger manager type is configured to match the existing layout in the metadata store"],"exampleFix":"// before\nlong id = lm.getLedgerId(\"/ledgers/0001/0234\"); // throws if prefix != ledgerRootPath\n// after\nString path = lm.getLedgerPath(ledgerId);\nif (path != null && path.startsWith(ledgerRootPath)) {\n    long id = lm.getLedgerId(path);\n}","handlingStrategy":"validation","validationCode":"if (path == null || !path.startsWith(ledgerRootPath + \"/\")) {\n    throw new IllegalArgumentException(\"not a valid long-hierarchical ledger path: \" + path);\n}","typeGuard":"static boolean isValidLedgerPath(String path, String ledgerRootPath) {\n    return path != null && path.startsWith(ledgerRootPath)\n        && path.length() > ledgerRootPath.length() + 1;\n}","tryCatchPattern":"try {\n    long id = lm.getLedgerId(path);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"it is not a valid hashed path name\")) {\n        LOG.error(\"Path {} does not match ledgerRootPath={}\", path, ledgerRootPath);\n    }\n    throw e;\n}","preventionTips":["Only feed getLedgerId paths produced by getLedgerPath of the same manager","Keep ledgerRootPath config stable across restarts and migrations","Use the ledger manager type matching the existing cluster layout"],"tags":["bookkeeper","path-parsing","ledger-manager"],"backgroundTag":"invalid-path-format","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"}