{"record":{"id":"8ea79cc1b7d1172a","repo":"tonhowtf/omniget","slug":"probe-returned-http","errorCode":null,"errorMessage":"probe returned HTTP {}","messagePattern":"probe returned HTTP (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/http_fetcher.rs","lineNumber":724,"sourceCode":"                    .map(|s| s.to_string()),\n                filename: header_filename(h),\n                method: \"HEAD\",\n            });\n        }\n    }\n\n    let mut req = client.get(url).header(reqwest::header::RANGE, \"bytes=0-0\");\n    if let Some(h) = headers {\n        req = req.headers(headers_without_range(h));\n    }\n    let resp = match tokio::time::timeout(timeout, req.send()).await {\n        Ok(Ok(r)) => r,\n        Ok(Err(e)) => return Err(anyhow!(\"probe failed: {}\", e)),\n        Err(_) => return Err(anyhow!(\"probe timed out\")),\n    };\n    let status = resp.status();\n    if !status.is_success() {\n        return Err(anyhow!(\"probe returned HTTP {}\", status));\n    }\n    let h = resp.headers().clone();\n    let content_type = h\n        .get(reqwest::header::CONTENT_TYPE)\n        .and_then(|v| v.to_str().ok())\n        .map(|s| s.to_string());\n    let filename = header_filename(&h);\n    let probe = if status == reqwest::StatusCode::PARTIAL_CONTENT {\n        RemoteProbe {\n            content_length: content_range_total(&h),\n            accept_ranges: true,\n            content_type,\n            filename,\n            method: \"GET range\",\n        }\n    } else {\n        RemoteProbe {\n            content_length: header_content_length(&h),","sourceCodeStart":706,"sourceCodeEnd":742,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/http_fetcher.rs#L706-L742","documentation":"probe_remote requires the ranged GET to return a success (2xx) status. Any non-success status — 403/404/405/500 etc. — is surfaced as `probe returned HTTP {status}` including the status code. Since HEAD succeeded earlier, this often reveals that the GET path is treated differently (e.g. HEAD allowed but GET forbidden).","triggerScenarios":"The bytes=0-0 GET response's resp.status() is not is_success(): 404 (URL gone), 403 (blocked), 405 (Range/method mishandling), 416 or 5xx from the origin.","commonSituations":"Hot-link protection / WAF rules returning 403, expired or moved download URLs returning 404, servers lacking range support returning 416, or origin 5xx during load.","solutions":["Read the status code in the message and look it up for the specific meaning (403 vs 404 vs 5xx).","Re-check the URL in a browser/curl to confirm the resource still exists and is public.","Add required auth headers/cookies — the probe forwards custom headers via headers_without_range, so supply them at the call site.","If the server lacks range support (416/405), it cannot be used for chunked download; fall back to single-stream download."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// pre-flight: issue the same ranged GET yourself and check status\nlet r = reqwest::get(format!(\"{url}\")).await?;\n// or check with headers attached as the library would:\n// reqwest::Client::new().get(url).header(\"Range\", \"bytes=0-0\")\nlet ok = r.status().is_success();","typeGuard":null,"tryCatchPattern":"match probe(url, headers, timeout).await {\n    Err(e) if e.to_string().starts_with(\"probe returned HTTP \") => {\n        let code: u16 = /* parse status from message */;\n        match code { 401 | 403 => /* add/refresh auth headers */, 404 => /* URL dead */, _ => /* server issue */ }\n    }\n    other => { other?; }\n}","preventionTips":["Pass all required auth/cookie headers to probe so the GET is authorized.","Validate download URLs (not expired/presigned-out) before probing.","Check server range support (Accept-Ranges header) before planning chunked downloads.","Treat repeated 5xx as host instability and back off."],"tags":["http","probe","http-status","network"],"backgroundTag":"http-error-response","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}