{"record":{"id":"aef30243b19a3fe0","repo":"apache/pulsar","slug":"no-offloader-found-for-driver-drivername-ple","errorCode":null,"errorMessage":"No offloader found for driver '${driverName}'. Please make sure you dropped the offloader nar packages under `${PULSAR_HOME}/offloaders`.","messagePattern":"No offloader found for driver '(.+?)'\\. Please make sure you dropped the offloader nar packages under `(.+?)/offloaders`\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"managed-ledger/src/main/java/org/apache/bookkeeper/mledger/offload/Offloaders.java","lineNumber":42,"sourceCode":"import lombok.CustomLog;\nimport lombok.Data;\nimport org.apache.bookkeeper.mledger.LedgerOffloaderFactory;\nimport org.apache.commons.lang3.tuple.Pair;\nimport org.apache.pulsar.common.nar.NarClassLoader;\n\n@CustomLog\n@Data\npublic class Offloaders implements AutoCloseable {\n\n    private final List<Pair<NarClassLoader, LedgerOffloaderFactory<?>>> offloaders = new ArrayList<>();\n\n    public LedgerOffloaderFactory<?> getOffloaderFactory(String driverName) throws IOException {\n        for (Pair<NarClassLoader, LedgerOffloaderFactory<?>> factory : offloaders) {\n            if (factory.getRight().isDriverSupported(driverName)) {\n                return factory.getRight();\n            }\n        }\n        throw new IOException(\"No offloader found for driver '\" + driverName + \"'.\"\n                + \" Please make sure you dropped the offloader nar packages under `${PULSAR_HOME}/offloaders`.\");\n    }\n\n    @Override\n    public void close() throws Exception {\n        offloaders.forEach(offloader -> {\n            try {\n                offloader.getRight().close();\n            } catch (Exception e) {\n                log.warn().attr(\"offloaderClass\", offloader.getRight().getClass())\n                        .attr(\"errorMessage\", e.getMessage())\n                        .log(\"Failed to close offloader\");\n            }\n            try {\n                offloader.getLeft().close();\n            } catch (IOException e) {\n                log.warn().attr(\"offloaderClass\", offloader.getRight().getClass())\n                        .attr(\"errorMessage\", e.getMessage())","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/managed-ledger/src/main/java/org/apache/bookkeeper/mledger/offload/Offloaders.java#L24-L60","documentation":"Offloaders loads LedgerOffloaderFactory implementations from NAR packages dropped in the PULSAR_HOME/offloaders directory. When no loaded factory supports the requested driver name, getOffloaderFactory throws this IOException. It means the storage offload driver (e.g. aws-s3, azureblob) requested by the broker config is not present on the classpath.","triggerScenarios":"Broker starts with offloadDriver set (or NamespaceOffload policies request offloading) but the offloader NAR was never installed; getOffloaderFactory(driverName) scans loaded offloaders and none reports isDriverSupported(driverName)==true.","commonSituations":"Fresh Pulsar installation without downloading tiered-storage offloader NARs; NAR placed in the wrong directory (PULSAR_HOME/offloaders not where the broker actually runs); driver name typo like 's3' vs 'aws-s3'; NAR version incompatible with the broker version.","solutions":["Download and install the matching offloader NAR package(s) into PULSAR_HOME/offloaders (e.g. from the pulsar-offloaders distribution of the same version)","Verify the directory broker.conf's offloadersDirectory points to actually contains the NAR files","Check the driver name in broker.conf offloadDriver / namespace policy matches a driver shipped in the installed NARs","Ensure offloader NAR version matches the Pulsar broker version"],"exampleFix":"// before (broker.conf)\noffloadDriver=aws-s3\n// no nar installed\n// after\n$ cp pulsar-offloaders/offloaders/*.nar $PULSAR_HOME/offloaders/","handlingStrategy":"validation","validationCode":"File offloadersDir = new File(System.getenv(\"PULSAR_HOME\"), \"offloaders\");\nboolean narsPresent = offloadersDir.isDirectory()\n    && offloadersDir.list((d, n) -> n.endsWith(\".nar\")).length > 0;\nif (!narsPresent) throw new IllegalStateException(\"No offloader .nar files in \" + offloadersDir);","typeGuard":null,"tryCatchPattern":"try {\n    LedgerOffloaderFactory<?> f = offloaders.getOffloaderFactory(driver);\n} catch (IOException e) {\n    log.error(\"Offloader driver {} not installed under PULSAR_HOME/offloaders\", driver, e);\n    throw new IllegalStateException(\"Install matching offloader NARs or fix offloadDriver=\" + driver, e);\n}","preventionTips":["Install the pulsar-offloaders distribution matching your broker version into PULSAR_HOME/offloaders","Keep offloadDriver names consistent between broker.conf and namespace policies","Add a pre-start check that offloaders/*.nar exists when tiered storage is enabled"],"tags":["configuration","offloading","startup"],"backgroundTag":"missing-offloader-nar","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"}