zed-industries/zed · error

failed to bind callback port

Error message

failed to bind callback port

What it means

For native app sign-in, Zed starts a tiny HTTP server on 127.0.0.1:0 (ephemeral port) to receive the OAuth redirect. This error means the loopback bind itself failed, so no callback can ever arrive.

Source

Thrown at crates/client/src/client.rs:1471

                        rpc::auth::keypair().context("failed to generate keypair for auth")?;
                    let public_key = String::try_from(public_key)
                        .context("failed to serialize public key for auth")?;

                    if let Some((login, token)) =
                        IMPERSONATE_LOGIN.as_ref().zip(ADMIN_API_TOKEN.as_ref())
                    {
                        if !*USE_WEB_LOGIN {
                            eprintln!("authenticate as admin {login}, {token}");

                            return this
                                .authenticate_as_admin(http, login.clone(), token.clone())
                                .await;
                        }
                    }

                    // Start an HTTP server to receive the redirect from Zed's sign-in page.
                    let server = tiny_http::Server::http("127.0.0.1:0")
                        .map_err(|e| anyhow!(e).context("failed to bind callback port"))?;
                    let port = server
                        .server_addr()
                        .to_ip()
                        .context("server not bound to a TCP address")?
                        .port();

                    #[derive(Serialize)]
                    struct NativeAppSignInQueryParams {
                        native_app_port: u16,
                        native_app_public_key: String,
                        system_id: Option<Arc<str>>,
                    }

                    // Open the Zed sign-in page in the user's browser, with query parameters that indicate
                    // that the user is signing in from a Zed app running on the same device.
                    let url = http.build_url(&format!(
                        "/native_app_signin?{}",
                        serde_urlencoded::to_string(&NativeAppSignInQueryParams {

View on GitHub (pinned to bc538def45)

Solutions

  1. Run Zed outside sandboxed/containerized environments that block loopback listeners
  2. Check for port exhaustion: close runaway local processes and retry
  3. Temporarily test with the app firewall/security agent disabled to confirm the blocker
Defensive patterns

Strategy: retry

Validate before calling

// probe loopback bind capability before starting sign-in
fn loopback_available() -> bool {
    std::net::TcpListener::bind("127.0.0.1:0").is_ok()
}
if !loopback_available() {
    anyhow::bail!("cannot bind loopback; native sign-in unavailable in this environment");
}

Try / catch

let server = match tiny_http::Server::http("127.0.0.1:0") {
    Ok(server) => server,
    Err(err) if err.kind() == std::io::ErrorKind::AddrInUse || err.kind() == std::io::ErrorKind::PermissionDenied => {
        // transient on busy systems; brief backoff then one retry
        std::thread::sleep(Duration::from_millis(500));
        tiny_http::Server::http("127.0.0.1:0").map_err(|e| anyhow!(e).context("failed to bind callback port"))?
    }
    Err(err) => return Err(anyhow!(err).context("failed to bind callback port")),
};

Prevention

When it happens

Trigger: tiny_http::Server::http("127.0.0.1:0") returns an error: the OS refuses new sockets — exhausted port range, sandbox denying network listeners, or restrictive container/MAC policies.

Common situations: Running Zed inside a sandboxed environment or container without loopback networking; systems with thousands of TIME_WAIT sockets; macOS application-firewall or endpoint-security agents blocking listeners.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/c0a739161dee94e6. Report an issue: GitHub.