{"record":{"id":"62745a4943741f4a","repo":"zed-industries/zed","slug":"unexpected-rpc-response-status","errorCode":null,"errorMessage":"unexpected /rpc response status {}","messagePattern":"unexpected /rpc response status (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/client/src/client.rs","lineNumber":1310,"sourceCode":"            #[cfg(any(test, feature = \"test-support\"))]\n            if let Some(url) = url_override {\n                return Ok(url);\n            }\n\n            if let Some(url) = &*ZED_RPC_URL {\n                return Url::parse(url).context(\"invalid rpc url\");\n            }\n\n            let mut url = http.build_url(\"/rpc\");\n            if let Some(preview_param) =\n                release_channel.and_then(|channel| channel.release_query_param())\n            {\n                url += \"?\";\n                url += preview_param;\n            }\n\n            let response = http.get(&url, Default::default(), false).await?;\n            anyhow::ensure!(\n                response.status().is_redirection(),\n                \"unexpected /rpc response status {}\",\n                response.status()\n            );\n            let collab_url = response\n                .headers()\n                .get(\"Location\")\n                .context(\"missing location header in /rpc response\")?\n                .to_str()\n                .map_err(EstablishConnectionError::other)?\n                .to_string();\n            Url::parse(&collab_url).with_context(|| format!(\"parsing collab rpc url {collab_url}\"))\n        }\n    }\n\n    fn establish_websocket_connection(\n        self: &Arc<Self>,\n        credentials: &Credentials,","sourceCodeStart":1292,"sourceCodeEnd":1328,"githubUrl":"https://github.com/zed-industries/zed/blob/bc538def4545534201bbfcac4e95ac34ea6501b6/crates/client/src/client.rs#L1292-L1328","documentation":"To discover the collab RPC endpoint, the client GETs /rpc and requires an HTTP 3xx redirect, reading the target from the Location header. Any non-redirect status (200, 404, 500, ...) fails with this error including the actual status code.","triggerScenarios":"The /rpc URL (optionally with a release-channel query param) responds without a redirection: the configured server does not implement the /rpc redirect, a reverse proxy answers the path itself, or an auth portal intercepts with 200.","commonSituations":"ZED_SERVER_URL pointing at a plain website or wrong subdomain; self-hosted setups where the redirect endpoint is missing; captive portals / SSO proxies returning 200 on all paths.","solutions":["Check the configured server URL and confirm `curl -I https://<server>/rpc` returns a 3xx with a Location header","Fix the reverse proxy so /rpc is passed through to the collab server instead of being intercepted","If running a custom server, redeploy a version that implements the /rpc redirect"],"exampleFix":"# verify expected behavior\n$ curl -sI https://zed.dev/rpc\nHTTP/2 302\nlocation: <collab-url>","handlingStrategy":"validation","validationCode":"# preflight: /rpc must redirect before pointing Zed at a custom server\nstatus=$(curl -s -o /dev/null -w '%{http_code}' \"https://$SERVER/rpc\")\ncase \"$status\" in 3*) ;; *) echo \"/rpc returned $status, not a redirect\" >&2; exit 2 ;; esac","typeGuard":null,"tryCatchPattern":"let response = http.get(&url, Default::default(), false).await?;\nif !response.status().is_redirection() {\n    // classify: 200 usually means a proxy intercepted; 404/5xx means wrong endpoint\n    log::warn!(\"/rpc returned {}; check server config\", response.status());\n    return Err(anyhow!(\"unexpected /rpc response status {}\", response.status()));\n}","preventionTips":["Validate custom server URLs with curl before configuring clients","Configure reverse proxies to pass /rpc through untouched","Alert on non-3xx /rpc responses in self-hosted monitoring"],"tags":["network","configuration","rpc","redirect"],"backgroundTag":null,"analyzedSha":"bc538def4545534201bbfcac4e95ac34ea6501b6","analyzedAt":"2026-08-16T07:30:46.435Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}