apache/pulsar · error · IOException
extension `${name}` does NOT provide a protocol handler impl
Error message
extension `${name}` does NOT provide a protocol handler implementation What it means
Thrown by ProxyExtensionsUtils.load when the NAR's ProxyExtensionDefinition metadata omits the extensionClass field. The NAR unpacks fine, but it does not point to any class implementing the proxy extension interface, so there is nothing to instantiate.
Source
Thrown at pulsar-proxy/src/main/java/org/apache/pulsar/proxy/extensions/ProxyExtensionsUtils.java:134
/**
* Load the extension according to the handler definition.
*
* @param metadata the extension definition.
* @return
*/
static ProxyExtensionWithClassLoader load(ProxyExtensionMetadata metadata,
String narExtractionDirectory) throws IOException {
final File narFile = metadata.getArchivePath().toAbsolutePath().normalize().toFile();
NarClassLoader ncl = NarClassLoaderBuilder.builder()
.narFile(narFile)
.parentClassLoader(ProxyExtension.class.getClassLoader())
.extractionDirectory(narExtractionDirectory)
.build();
ProxyExtensionDefinition phDef = getProxyExtensionDefinition(ncl);
if (StringUtils.isBlank(phDef.getExtensionClass())) {
throw new IOException("extension `" + phDef.getName() + "` does NOT provide a protocol"
+ " handler implementation");
}
try {
Class<?> extensionClass = ncl.loadClass(phDef.getExtensionClass());
Object extension = extensionClass.getDeclaredConstructor().newInstance();
if (!(extension instanceof ProxyExtension)) {
throw new IOException("Class " + phDef.getExtensionClass()
+ " does not implement extension interface");
}
ProxyExtension ph = (ProxyExtension) extension;
return new ProxyExtensionWithClassLoader(ph, ncl);
} catch (Throwable t) {
rethrowIOException(t);
return null;
}
}
View on GitHub (pinned to 820761864e)
Solutions
- Add the extensionClass property to the NAR's proxy extension definition file, pointing at the class implementing ProxyExtension
- Rebuild the extension NAR with the official Pulsar proxy-extension archetype/template so metadata is generated
- Re-download the official release NAR if the artifact came from a repository and may be corrupt
- Verify with 'unzip -p your.nar META-INF/proxyextension.yaml' that name and extensionClass are populated
Example fix
// before (META-INF/proxyextension.yaml) name: myext // after name: myext extensionClass: org.example.MyProxyExtension
Defensive patterns
Strategy: validation
Validate before calling
// Verify the NAR descriptor before loading
String yaml = readNarEntry(narFile, "META-INF/proxyextension.yaml");
if (yaml == null || !yaml.contains("extensionClass:"))
throw new IllegalStateException("NAR missing extensionClass in proxyextension.yaml"); Try / catch
try { proxyExtensions.load(conf); } catch (RuntimeException e) { if (e.getMessage().contains("does NOT provide")) log.error("Rebuild NAR: extensionClass missing from descriptor"); throw e; } Prevention
- Build custom NARs from the official Pulsar extension template
- Inspect META-INF/proxyextension.yaml in CI before publishing the artifact
When it happens
Trigger: Loading an extension NAR whose META-INF/proxyextension.yaml (ProxyExtensionDefinition) has a blank extensionClass property — typically a hand-built or mispackaged NAR missing the required descriptor entry.
Common situations: Building a custom extension NAR without adding extensionClass to the descriptor; packaging an empty/placeholder NAR; a broken release artifact from a CI pipeline that skipped the metadata generation step.
Related errors
- Failed to load the extension for extension name `${extension
- Malformed extension found for extension name `${extensionNam
- extension for `${extensionName}` attempts to use ${address}
- Class ${extensionClass} does not implement extension interfa
- Failed to bind extension `${extensionName}` on ${address}
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/3bc70c2872c5a085.
Report an issue: GitHub.