apache/pulsar · error · IOException
No offloader found for driver '${driverName}'. Please make s
Error message
No offloader found for driver '${driverName}'. Please make sure you dropped the offloader nar packages under `${PULSAR_HOME}/offloaders`. What it means
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.
Source
Thrown at managed-ledger/src/main/java/org/apache/bookkeeper/mledger/offload/Offloaders.java:42
import lombok.CustomLog;
import lombok.Data;
import org.apache.bookkeeper.mledger.LedgerOffloaderFactory;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.pulsar.common.nar.NarClassLoader;
@CustomLog
@Data
public class Offloaders implements AutoCloseable {
private final List<Pair<NarClassLoader, LedgerOffloaderFactory<?>>> offloaders = new ArrayList<>();
public LedgerOffloaderFactory<?> getOffloaderFactory(String driverName) throws IOException {
for (Pair<NarClassLoader, LedgerOffloaderFactory<?>> factory : offloaders) {
if (factory.getRight().isDriverSupported(driverName)) {
return factory.getRight();
}
}
throw new IOException("No offloader found for driver '" + driverName + "'."
+ " Please make sure you dropped the offloader nar packages under `${PULSAR_HOME}/offloaders`.");
}
@Override
public void close() throws Exception {
offloaders.forEach(offloader -> {
try {
offloader.getRight().close();
} catch (Exception e) {
log.warn().attr("offloaderClass", offloader.getRight().getClass())
.attr("errorMessage", e.getMessage())
.log("Failed to close offloader");
}
try {
offloader.getLeft().close();
} catch (IOException e) {
log.warn().attr("offloaderClass", offloader.getRight().getClass())
.attr("errorMessage", e.getMessage())View on GitHub (pinned to 820761864e)
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
Example fix
// before (broker.conf) offloadDriver=aws-s3 // no nar installed // after $ cp pulsar-offloaders/offloaders/*.nar $PULSAR_HOME/offloaders/
Defensive patterns
Strategy: validation
Validate before calling
File offloadersDir = new File(System.getenv("PULSAR_HOME"), "offloaders");
boolean narsPresent = offloadersDir.isDirectory()
&& offloadersDir.list((d, n) -> n.endsWith(".nar")).length > 0;
if (!narsPresent) throw new IllegalStateException("No offloader .nar files in " + offloadersDir); Try / catch
try {
LedgerOffloaderFactory<?> f = offloaders.getOffloaderFactory(driver);
} catch (IOException e) {
log.error("Offloader driver {} not installed under PULSAR_HOME/offloaders", driver, e);
throw new IllegalStateException("Install matching offloader NARs or fix offloadDriver=" + driver, e);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Could not open configuration file
- Malformed configuration file
- Need to specify a configuration file for broker
- Max message size need smaller than jvm directMemory
- The given supported namespace bundle split algorithm has una
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/aef30243b19a3fe0.
Report an issue: GitHub.