{"record":{"id":"3048f2a4ff098ede","repo":"Kuberwastaken/claurst","slug":"failed-to-read-oauth-callback-headers","errorCode":null,"errorMessage":"Failed to read OAuth callback headers: {}","messagePattern":"Failed to read OAuth callback headers: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"src-rust/crates/mcp/src/oauth.rs","lineNumber":261,"sourceCode":") -> anyhow::Result<String> {\n    let (mut socket, _) = tokio::time::timeout(Duration::from_secs(180), listener.accept())\n        .await\n        .map_err(|_| anyhow::anyhow!(\"Timeout waiting for OAuth callback\"))?\n        .map_err(|e| anyhow::anyhow!(\"Failed to accept OAuth callback connection: {}\", e))?;\n\n    let (reader, mut writer) = socket.split();\n    let mut reader = BufReader::new(reader);\n    let mut request_line = String::new();\n    reader\n        .read_line(&mut request_line)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to read OAuth callback request: {}\", e))?;\n    loop {\n        let mut header = String::new();\n        reader\n            .read_line(&mut header)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to read OAuth callback headers: {}\", e))?;\n        if header.trim().is_empty() {\n            break;\n        }\n    }\n\n    let path = request_line.split_whitespace().nth(1).unwrap_or(\"\");\n    let parsed_url = url::Url::parse(&format!(\"http://{}{}\", host, path))\n        .map_err(|e| anyhow::anyhow!(\"Failed to parse OAuth callback URL '{}': {}\", path, e))?;\n\n    let response = \"HTTP/1.1 200 OK\\r\\nContent-Type: text/plain; charset=utf-8\\r\\nConnection: close\\r\\n\\r\\nMCP OAuth authentication finished. You can close this tab.\\r\\n\";\n    writer\n        .write_all(response.as_bytes())\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to write OAuth callback response: {}\", e))?;\n\n    if parsed_url.path() != callback_path {\n        anyhow::bail!(\n            \"OAuth callback path mismatch: expected '{}', got '{}'\",","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/mcp/src/oauth.rs#L243-L279","documentation":"Thrown when read_line fails while consuming the HTTP header lines of the callback request (after the request line succeeded). The header-draining loop needs a complete header block before parsing the URL, and the socket failed mid-headers.","triggerScenarios":"wait_for_authorization_code's header-reading loop hits a socket error/reset — client closed early, OS socket timeout, or a non-HTTP client sending protocol-invalid data.","commonSituations":"Intermittent loopback flakiness; security software resetting the connection mid-request; extremely slow client hitting an OS socket timeout.","solutions":["Retry the authentication flow","Verify nothing on the host is resetting loopback connections (security agents, VPN filters)","Ensure the client hitting the callback is a real browser completing the OAuth redirect","Check the inner error for the specific io::Error kind and address it"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"Err(e) if e.to_string().contains(\"read OAuth callback headers\") => {\n    eprintln!(\"header read interrupted: {e}; retrying auth flow\");\n    run_mcp_auth_flow(server).await\n}","preventionTips":["Retry transient loopback read failures","Check for VPN/firewall software that resets local connections","Ensure only a real browser hits the callback endpoint"],"tags":["network","http","oauth"],"backgroundTag":"network-request-failed","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}