risingwavelabs/risingwave · error

Field '{}' not found in secret

Error message

Field '{}' not found in secret

What it means

The Vault KV-v2 response was parsed successfully, but the configured field (config.field) does not exist inside the secret's data map. The client reads exactly one named key from the secret payload, so a missing key aborts the conversion.

Source

Thrown at src/common/secret/src/vault_client.rs:265

        //         "version": 1
        //       }
        //     },
        //     "wrap_info": null,
        //     "warnings": null,
        //     "auth": null,
        //     "mount_type": "kv"
        //   }

        let secret_response: VaultSecretResponse = response
            .json()
            .await
            .context("Failed to parse Vault secret response")?;

        let field_value = secret_response
            .data
            .data
            .get(&self.config.field)
            .ok_or_else(|| anyhow::anyhow!("Field '{}' not found in secret", self.config.field))?;

        let secret_bytes = match field_value {
            Value::String(s) => s.as_bytes().to_vec(),
            _ => serde_json::to_vec(field_value)
                .context("Failed to serialize field value to bytes")?,
        };

        Ok(secret_bytes)
    }

    async fn get_token_internal(&self, force_refresh: bool) -> Result<String> {
        match &self.config.auth {
            HashiCorpVaultAuth::Token { auth_token } => Ok(auth_token.clone()),
            HashiCorpVaultAuth::AppRole {
                auth_role_id,
                auth_secret_id,
            } => {
                // Create cache key with vault base URL and role_id

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Compare the configured field name with the actual keys via 'vault kv get -format=json <path>' and correct the field in the secret definition
  2. Verify the secret path points at the intended secret
  3. Re-write the Vault secret to include the expected field if it was removed during rotation

Example fix

// before
CREATE SECRET s WITH (backend='hashicorp_vault', field='pwd', ...);
// after
CREATE SECRET s WITH (backend='hashicorp_vault', field='password', ...);
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the field exists before configuring the secret
let body: serde_json::Value = vault_kv_get(path).await?;
assert!(body["data"]["data"].get("password").is_some(), "field 'password' missing in secret");

Type guard

fn has_field(secret: &serde_json::Value, field: &str) -> bool {
    secret["data"]["data"].get(field).is_some()
}

Try / catch

match result {
    Err(e) if e.to_string().contains("not found in secret") => {
        eprintln!("check field name against 'vault kv get -format=json'");
    }
    other => other?,
}

Prevention

When it happens

Trigger: process_secret_response looks up self.config.field in the response's data.data JSON object and the key is absent — e.g. secret stores 'password' but the secret declaration asks for field 'pwd'.

Common situations: Field name typo in the CREATE SECRET definition; secret was rotated/rewritten with different keys; reading from the wrong secret path that has a different schema; KV-v1 vs KV-v2 path confusion yielding a differently-shaped payload.

Related errors


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