xai-org/grok-build · error

GCS download failed: {}

Error message

GCS download failed: {}

What it means

download_file fetches a session artifact from a signed GCS URL via the raw HTTP client. After sending the GET, any non-2xx status is converted into this error carrying the HTTP status code. It signals that the signed URL was rejected or the object is not retrievable, not a local I/O problem.

Source

Thrown at crates/codegen/xai-grok-shell/src/agent/session_registry_client.rs:368

        let url = format!("{}/sessions/{}/download", self.base_url, session_id);
        let builder = self
            .get(&url)
            .query(&[("file", file), ("turn", &turn.to_string())]);
        let (response, stamp) = self.send_authed(builder, "session download").await?;
        if !response.status().is_success() {
            return Err(self.check_response(response, stamp.as_ref(), "session download"));
        }
        let resp: DownloadResponse = response.json().await.context("parse download response")?;

        // Stream from the signed GCS URL directly to disk (archives can be hundreds of MB)
        let mut gcs_response = self
            .raw_client
            .get(&resp.download_url)
            .send()
            .await
            .context("download from GCS")?;
        if !gcs_response.status().is_success() {
            anyhow::bail!("GCS download failed: {}", gcs_response.status());
        }
        if let Some(parent) = dest.parent() {
            tokio::fs::create_dir_all(parent).await?;
        }
        let mut out = tokio::fs::File::create(dest)
            .await
            .context("create dest file")?;
        let chunk_timeout = std::time::Duration::from_secs(60);
        loop {
            match tokio::time::timeout(chunk_timeout, gcs_response.chunk()).await {
                Ok(Ok(Some(chunk))) => {
                    tokio::io::AsyncWriteExt::write_all(&mut out, &chunk)
                        .await
                        .context("write chunk to disk")?;
                }
                Ok(Ok(None)) => break,
                Ok(Err(e)) => return Err(e).context("read GCS chunk"),
                Err(_) => anyhow::bail!(

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Re-fetch a fresh download URL from the session registry and retry the download immediately
  2. Verify the object still exists in the GCS bucket (gsutil ls / console) for the session id
  3. Check network/proxy configuration so storage.googleapis.com is reachable
  4. Retry on 5xx with backoff; treat 403/404 as fatal and obtain a new session or artifact

Example fix

// before
let resp = client.raw_client.get(&stale_url).send().await?;
// after: obtain a fresh URL then retry once on failure
let resp = client.raw_client.get(&fresh_url).send().await?;
if !resp.status().is_success() {
    let fresh = registry.get_download_url(&session_id).await?;
    resp = client.raw_client.get(&fresh).send().await?;
}
Defensive patterns

Strategy: retry

Validate before calling

// Optionally pre-check reachability
let head = client.raw_client.head(&download_url).send().await?;
if !head.status().is_success() {
    eprintln!("download URL unusable ({}); refresh it", head.status());
}

Try / catch

match download_file(&client, &url, &dest).await {
    Ok(()) => {},
    Err(e) if e.to_string().contains("GCS download failed") => {
        let fresh = registry.get_download_url(&session_id).await?;
        download_file(&client, &fresh, &dest).await?;
    },
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling download_file (e.g. via the session registry client) when the GCS GET returns a non-success status such as 403 (expired/revoked signed URL), 404 (object deleted), or 5xx from Google Cloud Storage.

Common situations: Signed download URLs expiring before use, artifacts garbage-collected after a session is reaped, proxy/firewall blocking storage.googleapis.com, or GCS transient outages returning 500/503.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/1aff7517e0b2893e. Report an issue: GitHub.