{"record":{"id":"42d0f6ccbd65c9e7","repo":"apache/pulsar","slug":"kubernetes-secret-should-contain-key-information","errorCode":null,"errorMessage":"Kubernetes Secret should contain key information","messagePattern":"Kubernetes Secret should contain key information","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/secrets/src/main/java/org/apache/pulsar/functions/secretsproviderconfigurator/KubernetesSecretsProviderConfigurator.java","lineNumber":135,"sourceCode":"    public void doAdmissionChecks(AppsV1Api appsV1Api, CoreV1Api coreV1Api, String jobNamespace, String jobName,\n                                  FunctionDetails functionDetails) {\n        if (!StringUtils.isEmpty(functionDetails.getSecretsMap())) {\n            Type type = new TypeToken<Map<String, Object>>() {\n            }.getType();\n            Map<String, Object> secretsMap = new Gson().fromJson(functionDetails.getSecretsMap(), type);\n\n            for (Object object : secretsMap.values()) {\n                if (object instanceof Map) {\n                    @SuppressWarnings(\"unchecked\") // secret values are expected to be Map<String, String>\n                    Map<String, String> kubernetesSecret = (Map<String, String>) object;\n                    if (kubernetesSecret.size() < 2) {\n                        throw new IllegalArgumentException(\"Kubernetes Secret should contain id and key\");\n                    }\n                    if (!kubernetesSecret.containsKey(idKey)) {\n                        throw new IllegalArgumentException(\"Kubernetes Secret should contain id information\");\n                    }\n                    if (!kubernetesSecret.containsKey(keyKey)) {\n                        throw new IllegalArgumentException(\"Kubernetes Secret should contain key information\");\n                    }\n                } else {\n                    throw new IllegalArgumentException(\"Kubernetes Secret should be a Map containing id/key pairs\");\n                }\n            }\n        }\n    }\n}\n","sourceCodeStart":117,"sourceCodeEnd":144,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/secrets/src/main/java/org/apache/pulsar/functions/secretsproviderconfigurator/KubernetesSecretsProviderConfigurator.java#L117-L144","documentation":"In doAdmissionChecks, each Kubernetes secret entry must contain the key field ('key') naming which key inside the Kubernetes Secret to expose. If the entry is a Map containing 'id' but missing keyKey, this IllegalArgumentException is thrown.","triggerScenarios":"doAdmissionChecks receives a secrets entry like {\"id\": \"db-creds\"} or {\"id\": \"db-creds\", \"optional\": \"true\"} — a Map that identifies the Kubernetes Secret but not the key inside it.","commonSituations":"users think specifying the secret name is enough and expect all keys to be mounted; truncation of config when only one field was serialized; mixing the ClearSecretsProvider plain-string format with the K8s format.","solutions":["Add the 'key' field naming the entry inside the Kubernetes Secret: {\"id\": \"<secret-name>\", \"key\": \"<key-inside-secret>\"}","Create the needed key in the Kubernetes Secret and reference it in your secrets config","Validate each secret entry has both id and key before submitting the function"],"exampleFix":"// before\nsecrets: {\"mysecret\": {\"id\": \"db-creds\"}}\n// after\nsecrets: {\"mysecret\": {\"id\": \"db-creds\", \"key\": \"password\"}}","handlingStrategy":"validation","validationCode":"void requireSecretKey(Map<String, Object> secrets) {\n    for (Map.Entry<String, Object> e : secrets.entrySet()) {\n        Map<?, ?> m = (Map<?, ?>) e.getValue();\n        if (!m.containsKey(\"key\")) {\n            throw new IllegalArgumentException(\"Secret '\" + e.getKey() + \"' missing 'key'\");\n        }\n    }\n}","typeGuard":"static boolean hasSecretKey(Object v) {\n    return v instanceof Map<?, ?> m && m.containsKey(\"key\");\n}","tryCatchPattern":"try {\n    admin.functions().createFunction(functionConfig);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"key information\")) { /* add 'key' field naming the k8s secret entry */ }\n}","preventionTips":["Each secret entry needs both the k8s Secret name (id) and the entry inside it (key)","Verify referenced keys exist in the Kubernetes Secret before deploying","Use helm/kubectl to cross-check secret keys referenced by function configs"],"tags":["kubernetes","secrets","validation","pulsar-functions"],"backgroundTag":"secret-config-validation","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}