{"record":{"id":"062bcacb5d5056e8","repo":"apache/pulsar","slug":"unknown-function-runtime","errorCode":null,"errorMessage":"Unknown function runtime ","messagePattern":"Unknown function runtime ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/secrets/src/main/java/org/apache/pulsar/functions/secretsproviderconfigurator/KubernetesSecretsProviderConfigurator.java","lineNumber":58,"sourceCode":" * to ensure that the secrets are available to the function at runtime. Then we plug in the\n * EnvironmentBasedSecretsConfig as the secrets provider who knows how to read these environment variables.\n */\npublic class KubernetesSecretsProviderConfigurator implements SecretsProviderConfigurator {\n    private static String idKey = \"path\";\n    private static String keyKey = \"key\";\n\n    @Override\n    public String getSecretsProviderClassName(FunctionDetails functionDetails) {\n        switch (functionDetails.getRuntime()) {\n            case JAVA:\n                return EnvironmentBasedSecretsProvider.class.getName();\n            case PYTHON:\n                return \"secretsprovider.EnvironmentBasedSecretsProvider\";\n            case GO:\n                // [TODO] See GH issue #8425, we should finish this part once the issue is resolved.\n                return \"\";\n            default:\n                throw new RuntimeException(\"Unknown function runtime \" + functionDetails.getRuntime());\n        }\n    }\n\n    @Override\n    public Map<String, String> getSecretsProviderConfig(FunctionDetails functionDetails) {\n        return null;\n    }\n\n    // Kubernetes secrets can be exposed as volume mounts or as\n    // environment variables in the pods. We are currently using the\n    // environment variables way. Essentially the secretName/secretPath\n    // is attached as secretRef to the environment variables\n    // of a pod and kubernetes magically makes the secret pointed to by this combination available as a env variable.\n    @Override\n    public void configureKubernetesRuntimeSecretsProvider(V1PodSpec podSpec, String functionsContainerName,\n                                                          FunctionDetails functionDetails) {\n        V1Container container = null;\n        for (V1Container v1Container : podSpec.getContainers()) {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/secrets/src/main/java/org/apache/pulsar/functions/secretsproviderconfigurator/KubernetesSecretsProviderConfigurator.java#L40-L76","documentation":"KubernetesSecretsProviderConfigurator.getSecretsProviderClassName() maps JAVA/PYTHON runtimes to environment-based secrets providers; any other runtime value falls into default and throws RuntimeException(\"Unknown function runtime ...\"). GO returns \"\" pending GH issue #8425, so the throw fires only for values outside the known switch.","triggerScenarios":"Invoking getSecretsProviderClassName with a FunctionDetails having an unrecognized runtime enum (unset/unspecified or a newer runtime value unknown to this configurator) while running functions on Kubernetes with the Kubernetes secrets provider configurator.","commonSituations":"Version skew between function worker and function proto definitions; functions submitted with runtime left defaulted; custom runtime values in patched builds.","solutions":["Set runtime explicitly to JAVA or PYTHON when submitting the function for a Kubernetes deployment.","Upgrade/downgrade function worker so the Runtime enum matches the one used at submission.","Validate the submitted FunctionDetails proto (runtime field) before dispatch.","Extend the configurator's switch if a new runtime type was introduced."],"exampleFix":"// before\n.setRuntime(FunctionDetails.Runtime.RUNTIME_UNSPECIFIED)\n// after\n.setRuntime(FunctionDetails.Runtime.JAVA)","handlingStrategy":"validation","validationCode":"FunctionDetails.Runtime rt = functionDetails.getRuntime();\nif (rt != FunctionDetails.Runtime.JAVA && rt != FunctionDetails.Runtime.PYTHON && rt != FunctionDetails.Runtime.GO) {\n  throw new IllegalArgumentException(\"Kubernetes secrets provider supports JAVA/PYTHON/GO only, got: \" + rt);\n}","typeGuard":"boolean k8sSecretsSupported(FunctionDetails d) { switch (d.getRuntime()) { case JAVA: case PYTHON: case GO: return true; default: return false; } }","tryCatchPattern":"try { String cls = k8sConfigurator.getSecretsProviderClassName(functionDetails); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Unknown function runtime\")) { log.error(\"Runtime {} unknown to this worker; check version skew\", functionDetails.getRuntime()); } throw e; }","preventionTips":["Set runtime explicitly at function submission on Kubernetes.","Keep the k8s function worker's proto/enum definitions in sync with brokers.","Reject unset runtime values at submission time.","Re-check the configurator's switch after any Pulsar upgrade adding new runtimes."],"tags":["kubernetes","function-runtime","secrets-provider","enum"],"backgroundTag":"unknown-runtime","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"}