{"record":{"id":"fa123e737861e3fa","repo":"risingwavelabs/risingwave","slug":"vault-api-returned-error-status","errorCode":null,"errorMessage":"Vault API returned error status: {} - {}","messagePattern":"Vault API returned error status: (.+?) - (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/common/secret/src/vault_client.rs","lineNumber":214,"sourceCode":"                .client\n                .get(url.as_str())\n                .header(\"X-Vault-Token\", &token)\n                .send()\n                .await\n                .context(\"Failed to send request to Vault\")?;\n\n            // Handle authentication failures - token may have been rotated/revoked\n            if (response.status() == 401 || response.status() == 403)\n                && retry_count == 0\n                && matches!(self.config.auth, HashiCorpVaultAuth::AppRole { .. })\n            {\n                // this case means the token changed during cache, need to trigger a refresh\n                force_refresh_token = true;\n                continue;\n            }\n\n            if !response.status().is_success() {\n                return Err(anyhow::anyhow!(\n                    \"Vault API returned error status: {} - {}\",\n                    response.status(),\n                    response.text().await.unwrap_or_default()\n                ));\n            }\n\n            // Success case - process the response and break out of retry loop\n            return self.process_secret_response(response).await;\n        }\n\n        // todo: refine error message\n        Err(anyhow::anyhow!(\"Failed to get secret from Vault\"))\n    }\n\n    async fn process_secret_response(&self, response: reqwest::Response) -> Result<Vec<u8>> {\n        // https://developer.hashicorp.com/vault/docs/secrets/kv/kv-v2/cookbook/read-data\n        // a demo response:\n        //   {","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/common/secret/src/vault_client.rs#L196-L232","documentation":"The Vault HTTP API responded with a non-2xx status during a secret read. The error embeds the HTTP status code and the raw response body, so it captures any server-side rejection (auth failure, permission denied, malformed path, server error). It is thrown after the token-refresh retry logic decides the response is final.","triggerScenarios":"get_secret issues a KV-v2 read request and the response status is not success (e.g. 403 ACL denial, 404 unknown path/mount, 503 Vault sealed/standby).","commonSituations":"Wrong secret path or mount point; Vault policy does not grant read on the path; Vault is sealed or unreachable backend; token lacks capabilities after policy change.","solutions":["Read the status and body in the error message to identify the cause (404 = wrong path, 403 = permissions, 503 = sealed/unavailable)","Verify the secret path and KV mount point match the actual Vault layout (KV-v2 paths need data/ prefix handled by the client)","Check the token's policies grant 'read' on the secret path via 'vault policy read'","If 503, unseal Vault or check cluster health"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Check Vault health before reading secrets\nlet healthy = reqwest::get(format!(\"{}/v1/sys/health\", vault_addr)).await?.status().is_success();\nif !healthy { /* unseal or fix Vault first */ }","typeGuard":null,"tryCatchPattern":"match client.get_secret().await {\n    Err(e) if e.to_string().contains(\"403\") => fix_policy_and_retry(),\n    Err(e) if e.to_string().contains(\"503\") => unseal_vault_and_retry(),\n    Err(e) => return Err(e),\n    Ok(v) => Ok(v),\n}","preventionTips":["Grant the Vault token 'read' capability on the secret path","Verify the KV mount version (v1 vs v2) and path before configuring","Monitor Vault health/seal status in production"],"tags":["vault","http","network"],"backgroundTag":"http-error-response","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"}