apache/pulsar · error · RuntimeException
No FunctionContainer found
Error message
No FunctionContainer found
What it means
KubernetesSecretsProviderConfigurator.configureKubernetesRuntimeSecretsProvider() scans the function pod spec's containers for one named functionsContainerName (typically 'function'). If no container matches after the loop, it throws RuntimeException("No FunctionContainer found") because it cannot attach secret env vars to the pod spec.
Source
Thrown at pulsar-functions/secrets/src/main/java/org/apache/pulsar/functions/secretsproviderconfigurator/KubernetesSecretsProviderConfigurator.java:83
}
// Kubernetes secrets can be exposed as volume mounts or as
// environment variables in the pods. We are currently using the
// environment variables way. Essentially the secretName/secretPath
// is attached as secretRef to the environment variables
// of a pod and kubernetes magically makes the secret pointed to by this combination available as a env variable.
@Override
public void configureKubernetesRuntimeSecretsProvider(V1PodSpec podSpec, String functionsContainerName,
FunctionDetails functionDetails) {
V1Container container = null;
for (V1Container v1Container : podSpec.getContainers()) {
if (v1Container.getName().equals(functionsContainerName)) {
container = v1Container;
break;
}
}
if (container == null) {
throw new RuntimeException("No FunctionContainer found");
}
if (!StringUtils.isEmpty(functionDetails.getSecretsMap())) {
Type type = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> secretsMap = new Gson().fromJson(functionDetails.getSecretsMap(), type);
for (Map.Entry<String, Object> entry : secretsMap.entrySet()) {
final V1EnvVar secretEnv = new V1EnvVar();
@SuppressWarnings("unchecked") // secret values are expected to be Map<String, String>
Map<String, String> kv = (Map<String, String>) entry.getValue();
secretEnv.name(entry.getKey())
.valueFrom(new V1EnvVarSource()
.secretKeyRef(new V1SecretKeySelector()
.name(kv.get(idKey))
.key(kv.get(keyKey))));
container.addEnvItem(secretEnv);
}
}
}View on GitHub (pinned to 820761864e)
Solutions
- Ensure the function pod spec includes a container named 'function' (the default functionsContainerName), or update functionsContainerName in the worker's KubernetesRuntimeFactory config to match your custom container name.
- Remove/fix custom pod.yaml templates that rename the container.
- Check function worker config (k8s runtime settings) so the container name matches between pod creation and secrets configuration.
- Inspect the generated pod spec (kubectl get pod -o jsonpath='{.spec.containers[*].name}') to confirm names.
Example fix
// before (custom pod template)
containers:
- name: my-fn-container
image: ...
// after
containers:
- name: function
image: ... Defensive patterns
Strategy: validation
Validate before calling
boolean hasFunctionContainer = java.util.Arrays.stream(podSpec.getContainers())
.anyMatch(c -> c.getName().equals("function"));
if (!hasFunctionContainer) throw new IllegalStateException("Pod spec must contain a container named 'function'"); Type guard
boolean podHasFunctionContainer(io.kubernetes.client.openapi.models.V1PodSpec spec, String name) {
return spec != null && spec.getContainers() != null
&& spec.getContainers().stream().anyMatch(c -> name.equals(c.getName()));
} Try / catch
try { configurator.configureKubernetesRuntimeSecretsProvider(functionDetails, podSpec, containerName); } catch (RuntimeException e) { if ("No FunctionContainer found".equals(e.getMessage())) { log.error("Pod containers: {}", java.util.Arrays.toString(podSpec.getContainers().stream().map(c -> c.getName()).toArray())); } throw e; } Prevention
- Never rename the 'function' container in custom pod templates.
- Keep functionsContainerName config consistent with pod spec generation.
- Audit mutating webhooks that rewrite container names.
- Log container names from pod specs when debugging k8s function runtime.
When it happens
Trigger: Submitting/configuring a function on Kubernetes where the generated (or provided) pod spec has no container literally named after functionsContainerName — e.g. custom pod specs renamed the container, or the function worker built the pod without the expected 'function' container.
Common situations: Customized KubernetesRuntimeFactory container names; user-supplied pod templates overriding the container name; version changes where the default container name changed; mutating webhooks rewriting container names.
Related errors
- UNSUPPORTED_ISSUER
- Function runtime customizer %s must implement KubernetesMani
- 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
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/8366888052c0b11c.
Report an issue: GitHub.