{"record":{"id":"36bcfeaf32dabbae","repo":"zed-industries/zed","slug":"failed-to-bind-loopback-listener-for-oauth-callbac","errorCode":null,"errorMessage":"Failed to bind loopback listener for OAuth callback on {addr}","messagePattern":"Failed to bind loopback listener for OAuth callback on (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/oauth_callback_server/src/oauth_callback_server.rs","lineNumber":380,"sourceCode":"            .query()\n            .ok_or_else(|| anyhow!(\"OAuth callback has no query string\"))?;\n        OAuthCallbackParams::parse_query(query)\n    }\n\n    /// Callback path reserved for evicting a previously-running OAuth callback\n    /// server bound to the same port. Always handled, regardless of `config.path`.\n    const CANCEL_PATH: &str = \"/cancel\";\n\n    const BIND_MAX_ATTEMPTS: u32 = 10;\n    const BIND_RETRY_DELAY: Duration = Duration::from_millis(200);\n    const CANCEL_REQUEST_TIMEOUT: Duration = Duration::from_secs(2);\n\n    fn bind_callback_server(config: &OAuthCallbackServerConfig) -> Result<tiny_http::Server> {\n        // Ephemeral ports always succeed; skip the cancel-retry dance entirely.\n        if config.preferred_port == 0 {\n            let addr = format!(\"{}:0\", config.host);\n            return tiny_http::Server::http(&addr).map_err(|err| {\n                anyhow!(err).context(format!(\n                    \"Failed to bind loopback listener for OAuth callback on {addr}\"\n                ))\n            });\n        }\n\n        match try_bind_with_cancel(config.host, config.preferred_port) {\n            Ok(server) => Ok(server),\n            Err(primary_err) => {\n                let Some(fallback_port) = config.fallback_port else {\n                    return Err(primary_err.context(format!(\n                        \"Failed to bind loopback listener for OAuth callback on {}:{}\",\n                        config.host, config.preferred_port,\n                    )));\n                };\n                log::warn!(\n                    \"OAuth callback port {}:{} unavailable; falling back to port {}\",\n                    config.host,\n                    config.preferred_port,","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/oauth_callback_server/src/oauth_callback_server.rs#L362-L398","documentation":"Bind failure in bind_callback_server: the loopback listener could not be opened on the target address (typically the port is already taken by a previous callback server); within the retry loop this error triggers a cancel request against the stale occupant before retrying.","triggerScenarios":"Thrown at crates/oauth_callback_server/src/oauth_callback_server.rs:380 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the sign-in; the server first tries to cancel the stale occupant and rebind","Manually close the process holding the port if rebinding keeps failing","Configure a different port/path via start_oauth_callback_server_with_config"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}