apache/pulsar · error · IllegalArgumentException
Function runtime customizer %s must implement KubernetesMani
Error message
Function runtime customizer %s must implement KubernetesManifestCustomizer
What it means
KubernetesRuntimeFactory.initialize validates that the configured function runtime customizer class implements KubernetesManifestCustomizer before using it. If a class was configured via functionsWorkerCustomNarWindowTitle/customizer property but does not implement the required interface, initialization fails fast with IllegalArgumentException.
Source
Thrown at pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/runtime/kubernetes/KubernetesRuntimeFactory.java:232
this.functionInstanceMinResources = workerConfig.getFunctionInstanceMinResources();
this.functionInstanceMaxResources = workerConfig.getFunctionInstanceMaxResources();
this.functionInstanceResourceGranularities = workerConfig.getFunctionInstanceResourceGranularities();
this.functionInstanceResourceChangeInLockStep = workerConfig.isFunctionInstanceResourceChangeInLockStep();
this.secretsProviderConfigurator = secretsProviderConfigurator;
this.authenticationEnabled = workerConfig.isAuthenticationEnabled();
this.javaInstanceJarFile = this.pulsarRootDir + "/instances/java-instance.jar";
this.pythonInstanceFile = this.pulsarRootDir + "/instances/python-instance/python_instance_main.py";
this.serverCaBytes = workerConfig.getTlsTrustChainBytes();
try {
setupClient();
} catch (Exception e) {
log.error().exception(e).log("Failed to setup client");
throw new RuntimeException(e);
}
// make sure the provided class is a kubernetes auth provider, this needs to run before the authProvider!
if (runtimeCustomizer.isPresent()) {
if (!(runtimeCustomizer.get() instanceof KubernetesManifestCustomizer)) {
throw new IllegalArgumentException("Function runtime customizer "
+ runtimeCustomizer.get().getClass().getName()
+ " must implement KubernetesManifestCustomizer");
} else {
KubernetesManifestCustomizer manifestCustomizer =
(KubernetesManifestCustomizer) runtimeCustomizer.get();
this.manifestCustomizer = Optional.of(manifestCustomizer);
}
} else {
this.manifestCustomizer = Optional.empty();
}
// make sure the provided class is a kubernetes auth provider
if (functionAuthProvider.isPresent()) {
if (!(functionAuthProvider.get() instanceof KubernetesFunctionAuthProvider)) {
throw new IllegalArgumentException("Function authentication provider "
+ functionAuthProvider.get().getClass().getName()
+ " must implement KubernetesFunctionAuthProvider");
} else {View on GitHub (pinned to 820761864e)
Solutions
- Make the configured class implement org.apache.pulsar.functions.runtime.kubernetes.KubernetesManifestCustomizer.
- Verify the class name in functions_worker.yml points to the Kubernetes manifest customizer, not another runtime's customizer.
- Check the Pulsar version docs: ensure the interface name matches the version deployed (interface has changed across releases).
- Rebuild/redeploy the custom NAR containing the corrected class.
Example fix
// before
public class MyCustomizer implements RuntimeCustomizer { ... }
// after
public class MyCustomizer implements KubernetesManifestCustomizer { ... } Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = Class.forName(configuredCustomizerClassName);
if (!KubernetesManifestCustomizer.class.isAssignableFrom(c)) {
throw new IllegalArgumentException(configuredCustomizerClassName + " must implement KubernetesManifestCustomizer");
} Type guard
boolean isValidCustomizer(Object o) { return o instanceof KubernetesManifestCustomizer; } Try / catch
try { factory.initialize(...); } catch (IllegalArgumentException e) { if (e.getMessage().contains("KubernetesManifestCustomizer")) { log.fatal("Bad customizer config"); } throw e; } Prevention
- Verify the configured class implements KubernetesManifestCustomizer, not a generic RuntimeCustomizer
- Recompile custom NARs against the deployed Pulsar version
- Smoke-test worker startup in CI after changing functions_worker.yml
When it happens
Trigger: Setting the runtime customizer class name (functionRuntimeCustomizer config in functions_worker.yml) to a class that exists but implements a different customizer interface (e.g. a generic RuntimeCustomizer or wrong plugin class), causing the instanceof KubernetesManifestCustomizer check at line 232 to fail.
Common situations: Copy-pasting a customizer class name from another runtime (e.g. process/thread runtime customizer); upgrading Pulsar where the customizer interface was renamed/split; typos leading to a similarly-named wrong class; custom NAR containing an unrelated class.
Related errors
- Function authentication provider %s must implement Kubernete
- Per instance cpu requested, %s, for function should be posit
- Per instance ram requested, %s, for function should be posit
- Per instance cpu requested, %s, ram requested, %s, for funct
- KubernetesSecretsProviderConfigurator should only be setup f
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/f86c758b749c922a.
Report an issue: GitHub.