tonhowtf/omniget · error

Instagram GQL retornou HTTP

Error message

Instagram GQL retornou HTTP {}

What it means

request_gql posts to Instagram's GraphQL endpoint with an anonymous cookie; any non-2xx HTTP status aborts with this error embedding the status code. It means the transport-level request succeeded but Instagram rejected it at HTTP level rather than returning a JSON payload.

Solutions

  1. Log the embedded status code: 429 → back off and retry with exponential delay; 401/403 → refresh the anonymous cookie and required headers (x-ig-app-id, X-CSRFToken).
  2. Re-fetch a fresh anonymous cookie before retrying — stale cookies are a common cause of 403s.
  3. Add per-request jitter/throttling to stay under Instagram's rate limits.
  4. If 403 persists, update the client headers to match the current Instagram web app; check the library for newer versions.

Example fix

// before
let response = self.client.post(&gql_url).header("Cookie", &anon_cookie).body(body).send().await?;
if !response.status().is_success() {
    return Err(anyhow!("Instagram GQL retornou HTTP {}", response.status()));
}
// after
let response = self.client.post(&gql_url).header("Cookie", &anon_cookie).body(body).send().await?;
match response.status() {
    s if s.as_u16() == 429 => {
        tokio::time::sleep(Duration::from_secs(30)).await;
        return self.request_gql(shortcode).await; // retry once after backoff
    }
    s if !s.is_success() => anyhow::bail!("Instagram GQL retornou HTTP {}", s),
    _ => {}
}
Defensive patterns

Strategy: retry

Validate before calling

// Before the GQL call, confirm you have a fresh anonymous cookie:
// let anon_cookie = fetch_anon_cookie().await?;
// anyhow::ensure!(!anon_cookie.is_empty(), "missing Instagram anonymous cookie");

Try / catch

async fn gql_with_retry(client: &Client, body: String, attempts: u32) -> anyhow::Result<Response> {
    for i in 0..attempts {
        let resp = client.post(GQL_URL).header("Cookie", &anon_cookie).body(body.clone()).send().await?;
        match resp.status().as_u16() {
            200 => return Ok(resp),
            429 => tokio::time::sleep(Duration::from_secs(5 * 2u64.pow(i))).await,
            401 | 403 => refresh_anon_cookie().await?,
            s => anyhow::bail!("Instagram GQL retornou HTTP {}", s),
        }
    }
    anyhow::bail!("gql retries exhausted")
}

Prevention

When it happens

Trigger: request_gql receives a response whose status().is_success() is false — e.g. 401/403 for blocked/absent anonymous cookie, 429 rate limiting, 5xx from Instagram, or a 404 after endpoint changes.

Common situations: Sending GQL queries too fast and getting 429; Instagram rotating endpoint requirements and returning 403 for missing headers (x-ig-app-id, csrf); anonymous cookie stale/expired; scraping from cloud IPs that Instagram blocks outright.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/ebadee167c65921d. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/platforms/instagram.rs:423

            .header("Content-Type", "application/x-www-form-urlencoded")
            .header("Sec-Fetch-Dest", "empty")
            .header("Sec-Fetch-Mode", "cors")
            .header("Sec-Fetch-Site", "same-origin")
            .header("X-Requested-With", "XMLHttpRequest")
            .header("x-ig-app-id", &params.app_id)
            .header("X-FB-LSD", &params.lsd_token)
            .header("X-CSRFToken", &params.csrf_token)
            .header("X-FB-Friendly-Name", "PolarisPostActionLoadPostQueryQuery")
            .header("x-asbd-id", "129477")
            .header("X-Bloks-Version-Id", &params.bloks_version_id)
            .header("Referer", "https://www.instagram.com/")
            .header("Cookie", &anon_cookie)
            .body(body)
            .send()
            .await?;

        if !response.status().is_success() {
            return Err(anyhow!("Instagram GQL retornou HTTP {}", response.status()));
        }

        let json: serde_json::Value = response.json().await?;

        let data = json
            .get("data")
            .ok_or_else(|| anyhow!("Resposta GQL sem data"))?;

        let media = data
            .get("xdt_shortcode_media")
            .or_else(|| data.get("shortcode_media"));

        match media {
            Some(m) if !m.is_null() => Ok(m.clone()),
            _ => Err(anyhow!("Post not found via GQL")),
        }
    }

View on GitHub (pinned to 8600b91f42)