zed-industries/zed · error

Failed to bind loopback listener for OAuth callback on {addr

Error message

Failed to bind loopback listener for OAuth callback on {addr}

What it means

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.

Source

Thrown at crates/oauth_callback_server/src/oauth_callback_server.rs:380

            .query()
            .ok_or_else(|| anyhow!("OAuth callback has no query string"))?;
        OAuthCallbackParams::parse_query(query)
    }

    /// Callback path reserved for evicting a previously-running OAuth callback
    /// server bound to the same port. Always handled, regardless of `config.path`.
    const CANCEL_PATH: &str = "/cancel";

    const BIND_MAX_ATTEMPTS: u32 = 10;
    const BIND_RETRY_DELAY: Duration = Duration::from_millis(200);
    const CANCEL_REQUEST_TIMEOUT: Duration = Duration::from_secs(2);

    fn bind_callback_server(config: &OAuthCallbackServerConfig) -> Result<tiny_http::Server> {
        // Ephemeral ports always succeed; skip the cancel-retry dance entirely.
        if config.preferred_port == 0 {
            let addr = format!("{}:0", config.host);
            return tiny_http::Server::http(&addr).map_err(|err| {
                anyhow!(err).context(format!(
                    "Failed to bind loopback listener for OAuth callback on {addr}"
                ))
            });
        }

        match try_bind_with_cancel(config.host, config.preferred_port) {
            Ok(server) => Ok(server),
            Err(primary_err) => {
                let Some(fallback_port) = config.fallback_port else {
                    return Err(primary_err.context(format!(
                        "Failed to bind loopback listener for OAuth callback on {}:{}",
                        config.host, config.preferred_port,
                    )));
                };
                log::warn!(
                    "OAuth callback port {}:{} unavailable; falling back to port {}",
                    config.host,
                    config.preferred_port,

View on GitHub (pinned to f4178619ac)

Solutions

  1. Retry the sign-in; the server first tries to cancel the stale occupant and rebind
  2. Manually close the process holding the port if rebinding keeps failing
  3. Configure a different port/path via start_oauth_callback_server_with_config
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at crates/oauth_callback_server/src/oauth_callback_server.rs:380 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/36bcfeaf32dabbae. Report an issue: GitHub.