risingwavelabs/risingwave · error
secret_store_private_key is not configured
Error message
secret_store_private_key is not configured
What it means
Secrets in RisingWave are encrypted at rest with a cluster-wide private key (secret_store_private_key). get_encrypted_payload reads this key from meta node options before encrypting a secret value; if the option was never configured, encryption cannot proceed and the create/alter secret operation fails.
Source
Thrown at src/meta/src/rpc/ddl_controller.rs:848
) -> MetaResult<NotificationVersion> {
let version = self
.metadata_manager
.catalog_controller
.alter_database_resource_group(database_id, resource_group)
.await?;
Ok(version)
}
// The 'secret' part of the request we receive from the frontend is in plaintext;
// here, we need to encrypt it before storing it in the catalog.
fn get_encrypted_payload(&self, secret: &Secret) -> MetaResult<Vec<u8>> {
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 encrypted_payload = SecretEncryption::encrypt(
secret_store_private_key.as_slice(),
secret.get_value().as_slice(),
)
.context(format!("failed to encrypt secret {}", secret.name))?;
Ok(encrypted_payload
.serialize()
.context(format!("failed to serialize secret {}", secret.name))?)
}
async fn create_secret(&self, mut secret: Secret) -> MetaResult<NotificationVersion> {
// The 'secret' part of the request we receive from the frontend is in plaintext;
// here, we need to encrypt it before storing it in the catalog.
let secret_plain_payload = secret.value.clone();
let encrypted_payload = self.get_encrypted_payload(&secret)?;
secret.value = encrypted_payload;
View on GitHub (pinned to 6469eb736d)
Solutions
- Add secret_store_private_key to the meta node configuration and restart the meta service.
- Verify the key is present via risingwave.toml / meta opts before enabling secret workflows.
- If the key was lost, restore it from backups — an existing encrypted store needs the same key to remain readable.
Example fix
// before (risingwave.toml) [meta] # secret_store_private_key missing // after [meta] secret_store_private_key = "<base64-encoded-key>"
Defensive patterns
Strategy: validation
Validate before calling
// before CREATE SECRET, check config
let key = std::env::var("RW_SECRET_STORE_PRIVATE_KEY")
.or(meta_opts.secret_store_private_key.clone());
if key.is_none() { return Err("set secret_store_private_key in meta config first".into()); } Try / catch
match create_secret(...).await {
Err(e) if e.to_string().contains("secret_store_private_key is not configured") => configure_and_retry(),
other => other?,
} Prevention
- Set secret_store_private_key in meta config at provisioning time
- Validate meta opts at startup if secrets will be used
- Back up the key — loss makes existing encrypted secrets unreadable
When it happens
Trigger: Calling CREATE SECRET or ALTER SECRET when the meta node was started without secret_store_private_key in its configuration/opts.
Common situations: Deployments that never enabled the secret store feature attempting to use secrets; a config file copied between environments dropping the key; upgrading a cluster where the key was added to docs but not the actual meta opts.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- the key {} is set both in plaintext and secret
- secret_store_private_key is not configured
- failed to encrypt or decrypt the secret
- No auth method specified for Vault backend
- Field '{}' not found in secret
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/daab8f2773d08626.
Report an issue: GitHub.