{"record":{"id":"f1d8c19c32f07e84","repo":"tinyhumansai/openhuman","slug":"401-response-missing-parseable-www-authenticate","errorCode":null,"errorMessage":"401 response missing parseable WWW-Authenticate","messagePattern":"401 response missing parseable WWW-Authenticate","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/openhuman/mcp/http_client/client.rs","lineNumber":390,"sourceCode":"            .header(CONTENT_TYPE, \"application/json\")\n            .header(ACCEPT, MCP_HTTP_ACCEPT)\n            .body(serde_json::to_vec(&json!({\n                \"jsonrpc\": \"2.0\",\n                \"id\": self.next_id.fetch_add(1, Ordering::Relaxed),\n                \"method\": \"initialize\",\n                \"params\": {\n                    \"protocolVersion\": LATEST_PROTOCOL_VERSION,\n                    \"capabilities\": {},\n                    \"clientInfo\": self.client_info,\n                }\n            }))?);\n        let response = self.apply_auth(request, true).send().await?;\n        if response.status() != reqwest::StatusCode::UNAUTHORIZED {\n            return Ok(None);\n        }\n\n        let challenge = parse_www_authenticate_challenge(response.headers())\n            .ok_or_else(|| anyhow::anyhow!(\"401 response missing parseable WWW-Authenticate\"))?;\n        let prm = if let Some(url) = challenge.resource_metadata.as_deref() {\n            Some(self.fetch_json::<ProtectedResourceMetadata>(url).await?)\n        } else {\n            None\n        };\n        let mut auth_servers = Vec::new();\n        if let Some(prm) = prm.as_ref() {\n            for issuer in &prm.authorization_servers {\n                if let Ok(metadata) = self.fetch_authorization_server_metadata(issuer).await {\n                    auth_servers.push(metadata);\n                }\n            }\n        }\n        Ok(Some(McpAuthorizationContext {\n            challenge,\n            protected_resource_metadata: prm,\n            authorization_server_metadata: auth_servers,\n        }))","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/mcp/http_client/client.rs#L372-L408","documentation":"During the initialize handshake the server answered HTTP 401, but the WWW-Authenticate header could not be parsed into an McpAuthChallenge (missing, malformed, or non-Standard scheme parameters). Without it the client cannot build the OAuth redirect for the user.","triggerScenarios":"Thrown at src/openhuman/mcp/http_client/client.rs:390 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the raw WWW-Authenticate header with curl to see its actual format","Have the user pre-authenticate via the OAuth connect flow so initialize no longer gets a 401","Report the server — an MCP 401 must carry a RFC 9728-conformant challenge"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}