{"record":{"id":"b779c99727505217","repo":"risingwavelabs/risingwave","slug":"secret-store-private-key-is-not-configured","errorCode":null,"errorMessage":"secret_store_private_key is not configured","messagePattern":"secret_store_private_key is not configured","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/meta/service/src/notification_service.rs","lineNumber":147,"sourceCode":"        let secrets = catalog_guard.list_secrets().await?;\n        let notification_version = self.env.notification_manager().current_version().await;\n\n        let decrypted_secrets = self.decrypt_secrets(secrets)?;\n\n        Ok((decrypted_secrets, notification_version))\n    }\n\n    fn decrypt_secrets(&self, secrets: Vec<Secret>) -> MetaResult<Vec<Secret>> {\n        // Skip getting `secret_store_private_key` if there is no secret\n        if secrets.is_empty() {\n            return Ok(vec![]);\n        }\n        let secret_store_private_key = self\n            .env\n            .opts\n            .secret_store_private_key\n            .clone()\n            .ok_or_else(|| anyhow!(\"secret_store_private_key is not configured\"))?;\n        let mut decrypted_secrets = Vec::with_capacity(secrets.len());\n        for mut secret in secrets {\n            let encrypted_secret = SecretEncryption::deserialize(secret.get_value())\n                .context(format!(\"failed to deserialize secret {}\", secret.name))?;\n            let decrypted_secret = encrypted_secret\n                .decrypt(secret_store_private_key.as_slice())\n                .context(format!(\"failed to decrypt secret {}\", secret.name))?;\n            secret.value = decrypted_secret;\n            decrypted_secrets.push(secret);\n        }\n        Ok(decrypted_secrets)\n    }\n\n    async fn get_worker_slot_mapping_snapshot(\n        &self,\n    ) -> MetaResult<(Vec<FragmentWorkerSlotMapping>, NotificationVersion)> {\n        let mappings = self\n            .metadata_manager","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/service/src/notification_service.rs#L129-L165","documentation":"decrypt_secrets requires the meta node's `secret_store_private_key` option to be set, because secrets stored in the meta store are encrypted and need this key for decryption. When the option is absent from MetaNodeOpts, the function returns an anyhow error instead of proceeding. This guards against silently returning unreadable secret values.","triggerScenarios":"Calling get_decrypted_secret_snapshot or frontend_subscribe on a meta node that was started without `secret_store_private_key` in its config/CLI options while secrets exist to be decrypted.","commonSituations":"Operator forgot to pass the private key when upgrading to secret-management features; environment uses encrypted secrets but the meta node config was regenerated without the key; local dev cluster launched with default opts that omit the key.","solutions":["Set `secret_store_private_key` in the meta node options (config file or `--secret-store-private-key`) and restart the meta service","Verify the key matches the one used when the secrets were originally encrypted, otherwise decryption will fail next","If secrets are not needed, avoid the API paths (get_decrypted_secret_snapshot/frontend_subscribe) or remove stored secrets"],"exampleFix":"// before (risingwave.toml for meta)\n[meta]\n# secret_store_private_key missing\n// after\n[meta]\nsecret_store_private_key = \"<base64 private key>\"","handlingStrategy":"validation","validationCode":"if meta_opts.secret_store_private_key.is_none() {\n    return Err(anyhow!(\"secret_store_private_key must be configured before decrypting secrets\"));\n}","typeGuard":"fn has_secret_key(opts: &MetaNodeOpts) -> bool { opts.secret_store_private_key.is_some() }","tryCatchPattern":null,"preventionTips":["Always include secret_store_private_key in meta node config when using secret management","Validate meta opts at startup, before serving RPCs","Keep the key in a managed secret store and inject it consistently across environments"],"tags":["rust","meta","secrets","config"],"backgroundTag":"missing-required-config-field","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}