{"record":{"id":"47278cb08ce0fc13","repo":"tonhowtf/omniget","slug":"probe-failed","errorCode":null,"errorMessage":"probe failed: {}","messagePattern":"probe failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/http_fetcher.rs","lineNumber":719,"sourceCode":"                content_length,\n                accept_ranges,\n                content_type: h\n                    .get(reqwest::header::CONTENT_TYPE)\n                    .and_then(|v| v.to_str().ok())\n                    .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,","sourceCodeStart":701,"sourceCodeEnd":737,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/http_fetcher.rs#L701-L737","documentation":"After the HEAD phase, probe_remote sends a 1-byte ranged GET (Range: bytes=0-0) to confirm the server supports range requests. Any reqwest error from that send (DNS, TLS, reset connection, response read failure) is reported as `probe failed: {e}`. Unlike 243/244 this arm covers non-connect transport errors and errors occurring after connect.","triggerScenarios":"The GET req.send() future inside tokio::time::timeout resolves Ok(Err(e)) — e.g. TLS handshake failure, connection reset mid-request, or an HTTP/2 protocol error — for a URL that passed (or skipped) the HEAD check.","commonSituations":"TLS certificate problems (self-signed, expired), HTTP/2 incompatibility, servers that accept connect then drop the request, or transient network flaps between the HEAD and GET phases.","solutions":["Read the wrapped reqwest cause for the precise transport failure.","Test the URL with `curl -v -r 0-0 <url>` to see the TLS/HTTP negotiation details.","Retry the probe; transient resets often resolve on a second attempt.","For TLS issues, add the missing root CA or disable/bypass h2 (http1_only) if the server mishandles HTTP/2."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match probe(url, headers, timeout).await {\n    Err(e) if e.to_string().starts_with(\"probe failed:\") => {\n        let cause = e.to_string(); // inspect reqwest cause: tls / reset / h2\n        if cause.contains(\"certificate\") { /* fix trust store or accept CA */ }\n    }\n    other => { other?; }\n}","preventionTips":["Keep the system CA bundle current to avoid TLS surprises.","Pin HTTP/1.1 for servers with flaky HTTP/2 support (reqwest http1_only).","Add a small retry for transient resets between HEAD and GET phases.","Test target URLs with curl -r 0-0 before wiring them into downloads."],"tags":["network","probe","http","reqwest"],"backgroundTag":"http-request-failed","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"}