Hmbown/CodeWhale · error

invalid MCP OAuth callback port 0

Error message

invalid MCP OAuth callback port 0

What it means

When constructing the OAuth callback listener (oauth.rs:785), an explicit callback_port of Some(0) is rejected. Port 0 normally means 'ask the OS for an ephemeral port' in socket APIs, but here that behavior is expressed by passing None (the code binds {bind_host}:0 for that); an explicit Some(0) is therefore treated as a config mistake rather than honored.

Source

Thrown at crates/tui/src/mcp/oauth.rs:785

    server_url: String,
}

impl OauthLoginFlow {
    #[allow(clippy::too_many_arguments)]
    async fn new(
        server_name: &str,
        server_url: &str,
        http_headers: HashMap<String, String>,
        env_headers: HashMap<String, String>,
        scopes: &[String],
        oauth_client_id: Option<&str>,
        oauth_resource: Option<&str>,
        callback_port: Option<u16>,
        callback_url: Option<&str>,
    ) -> Result<Self> {
        let bind_host = callback_bind_host(callback_url);
        let bind_addr = match callback_port {
            Some(0) => bail!("invalid MCP OAuth callback port 0"),
            Some(port) => format!("{bind_host}:{port}"),
            None => format!("{bind_host}:0"),
        };
        let listener = TcpListener::bind(&bind_addr)
            .await
            .map_err(|err| anyhow!(err))?;
        let redirect_uri = resolve_redirect_uri(&listener, callback_url)?;
        let callback_id = callback_id_from_server_url(server_url)?;
        let redirect_uri = append_callback_id_to_redirect_uri(&redirect_uri, &callback_id)?;
        let callback_path = callback_path_from_redirect_uri(&redirect_uri)?;

        let (tx, rx) = oneshot::channel();
        let guard = CallbackServerGuard {
            accept_task: spawn_callback_server(listener, tx, callback_path),
        };

        let headers = build_default_headers(&http_headers, &env_headers)?;
        let client = apply_default_headers(crate::tls::reqwest_client_builder(), &headers)

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Omit the callback port entirely (None) — the client binds an ephemeral port and derives the redirect URI from it
  2. Or specify a concrete free port in 1024-65535 that matches the redirect URI registered with the OAuth provider
  3. Fix generators/scripts so 'automatic' is expressed by absence, not by 0

Example fix

# before
/mcp login my-server --callback-port 0

# after
/mcp login my-server
Defensive patterns

Strategy: validation

Validate before calling

if let Some(port) = callback_port {
    ensure!(port != 0, "callback_port 0 is invalid; omit it for an ephemeral port");
}

Prevention

When it happens

Trigger: Invoking OAuth login with --callback-port 0, or a config/UI path that supplies callback_port: Some(0) to the callback server constructor.

Common situations: Users porting socket-code intuition ('pass 0 for a random port') to the OAuth callback config; automation scripts that default numeric options to 0; config generated by a tool that uses 0 as 'unset' sentinel.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/72ece2bf9d133811. Report an issue: GitHub.