risingwavelabs/risingwave · error · anyhow::Error

secret_store_private_key is not configured

Error message

secret_store_private_key is not configured

What it means

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.

Source

Thrown at src/meta/service/src/notification_service.rs:147

        let secrets = catalog_guard.list_secrets().await?;
        let notification_version = self.env.notification_manager().current_version().await;

        let decrypted_secrets = self.decrypt_secrets(secrets)?;

        Ok((decrypted_secrets, notification_version))
    }

    fn decrypt_secrets(&self, secrets: Vec<Secret>) -> MetaResult<Vec<Secret>> {
        // Skip getting `secret_store_private_key` if there is no secret
        if secrets.is_empty() {
            return Ok(vec![]);
        }
        let secret_store_private_key = self
            .env
            .opts
            .secret_store_private_key
            .clone()
            .ok_or_else(|| anyhow!("secret_store_private_key is not configured"))?;
        let mut decrypted_secrets = Vec::with_capacity(secrets.len());
        for mut secret in secrets {
            let encrypted_secret = SecretEncryption::deserialize(secret.get_value())
                .context(format!("failed to deserialize secret {}", secret.name))?;
            let decrypted_secret = encrypted_secret
                .decrypt(secret_store_private_key.as_slice())
                .context(format!("failed to decrypt secret {}", secret.name))?;
            secret.value = decrypted_secret;
            decrypted_secrets.push(secret);
        }
        Ok(decrypted_secrets)
    }

    async fn get_worker_slot_mapping_snapshot(
        &self,
    ) -> MetaResult<(Vec<FragmentWorkerSlotMapping>, NotificationVersion)> {
        let mappings = self
            .metadata_manager

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Set `secret_store_private_key` in the meta node options (config file or `--secret-store-private-key`) and restart the meta service
  2. Verify the key matches the one used when the secrets were originally encrypted, otherwise decryption will fail next
  3. If secrets are not needed, avoid the API paths (get_decrypted_secret_snapshot/frontend_subscribe) or remove stored secrets

Example fix

// before (risingwave.toml for meta)
[meta]
# secret_store_private_key missing
// after
[meta]
secret_store_private_key = "<base64 private key>"
Defensive patterns

Strategy: validation

Validate before calling

if meta_opts.secret_store_private_key.is_none() {
    return Err(anyhow!("secret_store_private_key must be configured before decrypting secrets"));
}

Type guard

fn has_secret_key(opts: &MetaNodeOpts) -> bool { opts.secret_store_private_key.is_some() }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/b779c99727505217. Report an issue: GitHub.