{"record":{"id":"cbda348276cf6e5c","repo":"kestra-io/kestra","slug":"cannot-find-secret-sub-key-s-in-secret-s","errorCode":null,"errorMessage":"Cannot find secret sub-key '%s' in secret '%s'.","messagePattern":"Cannot find secret sub-key '(.+?)' in secret '(.+?)'\\.","errorType":"exception","errorClass":"SecretNotFoundException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/functions/SecretFunction.java","lineNumber":97,"sourceCode":"                SecretObject secretObject = secretService.get().findSecretObject(flowTenantId, namespace, key);\n                consumeSecret(context, secretObject.value());\n\n                Map<String, Object> result = new LinkedHashMap<>();\n                result.put(VALUE_KEY, secretObject.value());\n                if (!secretObject.metadata().isEmpty()) {\n                    secretObject.metadata().values().forEach(value -> consumeSecret(context, value));\n                    result.put(METADATA_KEY, secretObject.metadata());\n                }\n                return result;\n            }\n\n            String secret = secretService.get().findSecret(flowTenantId, namespace, key);\n\n            if (subkey != null && !subkey.isEmpty()) {\n                try {\n                    JsonNode subkeys = OBJECT_MAPPER.readTree(secret);\n                    if (!subkeys.has(subkey)) {\n                        throw new SecretNotFoundException(\"Cannot find secret sub-key '\" + subkey + \"' in secret '\" + key + \"'.\");\n                    } else {\n                        JsonNode jsonNode = subkeys.get(subkey);\n                        secret = jsonNode.isValueNode() ? jsonNode.asText() : jsonNode.toString();\n                    }\n                } catch (JsonProcessingException e) {\n                    throw new SecretException(\n                        String.format(\n                            \"Failed to read secret sub-key '%s' from secret '%s'. Ensure the secret contains valid JSON value.\",\n                            subkey,\n                            key\n                        )\n                    );\n                }\n            }\n\n            consumeSecret(context, secret);\n            return secret;\n        } catch (SecretException | IOException e) {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/functions/SecretFunction.java#L79-L115","documentation":"When the secret() function is called with a 'subkey' argument, it loads the secret value, parses it as JSON, and looks for the given sub-key. If the JSON is valid but does not contain the requested key name, a SecretNotFoundException is thrown and wrapped as a PebbleException. This means the secret itself was found and is valid JSON, but the specific field within it is missing.","triggerScenarios":"Calling {{ secret('DB_CREDS', subkey='host') }} when the secret JSON is {\"username\":\"admin\",\"password\":\"secret\"} but has no 'host' field. Typo in the subkey name. The secret was updated and the field was renamed or removed.","commonSituations":"Secret schema changed (e.g., rotating from flat key names to nested structure). Typo in the subkey argument. Different environments (dev/prod) having different JSON structures for the same secret key.","solutions":["Verify the exact JSON structure of the secret in the secret backend and confirm the sub-key name exists.","Fix typos in the subkey argument (case-sensitive).","If you need the entire secret without a specific field, use full=true instead: {{ secret('KEY', full=true) }}.","Standardize the secret JSON schema across environments."],"exampleFix":"# before — subkey 'host' not in secret JSON {\"username\":\"admin\",\"password\":\"secret\"}\n{{ secret('DB_CREDS', subkey='host') }}\n\n# after — use the correct field name, or fetch full object\n{{ secret('DB_CREDS', subkey='username') }}\n# or inspect the full structure\n{{ secret('DB_CREDS', full=true) }}","handlingStrategy":"validation","validationCode":"# Before using a subkey, verify it exists in the secret's JSON.\n# Use full=true to inspect the structure first during development:\n# {{ secret('MY_KEY', full=true) }}\n# Then hardcode the confirmed subkey name:\n# {{ secret('MY_KEY', subkey='confirmed_field') }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Document the JSON schema of each secret so subkey names are known.","Standardize secret JSON structure across environments (dev, staging, prod).","Use full=true during development to inspect the actual secret structure before coding subkey access.","Watch for case sensitivity in JSON field names."],"tags":["pebble","secret","subkey","json","not-found"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}