databendlabs/databend · error

status code: , msg

Error message

status code: {status}, msg: {msg}

What it means

The meta control (metabench/metactl) HTTP client has a checked_get helper that treats any non-2xx admin API response as an error, embedding the HTTP status code and the response body message: 'status code: {status}, msg: {msg}'.

Solutions

  1. Check the status code and msg in the error to identify the server-side cause
  2. Verify the admin API address and path are correct for the running metasrv version
  3. Ensure no proxy is intercepting and returning gateway errors

Example fix

// before
metactl ... --admin-api-address http://localhost:8080  # wrong service
// after
metactl ... --admin-api-address http://localhost:28102  # metasrv admin api
Defensive patterns

Strategy: try-catch

Validate before calling

let resp = reqwest::get(url).await?;
if !resp.status().is_success() {
    eprintln!("admin api returned {}", resp.status());
}

Try / catch

match client.checked_get(path).await {
    Ok(resp) => handle(resp),
    Err(e) => eprintln!("admin request failed ({}); check status/msg embedded in error", e),
}

Prevention

When it happens

Trigger: checked_get is called (directly or via get_json/trigger_snapshot/get_metrics) and the admin API returns 4xx/5xx, e.g. wrong endpoint path, node unavailable behind a proxy, or API rejecting the request.

Common situations: Hitting a metasrv whose admin API is not enabled; wrong port routing to another service; server-side errors while triggering snapshots or reading metrics; proxy returning 502/503.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/b0e17637d0f3ac41. Report an issue: GitHub.

Appendix: source

Thrown at src/meta/control/src/admin.rs:49

            endpoint: format!("http://{}", addr),
        }
    }

    /// Send a GET request and return the response on success,
    /// or an error containing the status code and response body on failure.
    async fn checked_get(&self, path: &str) -> anyhow::Result<reqwest::Response> {
        let resp = self
            .client
            .get(format!("{}{path}", self.endpoint))
            .send()
            .await?;
        let status = resp.status();
        if status.is_success() {
            Ok(resp)
        } else {
            let data = resp.bytes().await?;
            let msg = String::from_utf8_lossy(&data);
            Err(anyhow::anyhow!("status code: {status}, msg: {msg}"))
        }
    }

    /// Send a GET request and deserialize the JSON response.
    async fn get_json<T: DeserializeOwned>(&self, path: &str) -> anyhow::Result<T> {
        let resp = self.checked_get(path).await?;
        Ok(resp.json().await?)
    }

    pub async fn status(&self) -> anyhow::Result<AdminStatusResponse> {
        self.get_json("/v1/cluster/status").await
    }

    /// Transfer raft leadership to the specified node, or to a random voter if `target` is `None`.
    pub async fn transfer_leader(
        &self,
        target: Option<u64>,
    ) -> anyhow::Result<AdminTransferLeaderResponse> {

View on GitHub (pinned to 288d84d76e)