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, an explicit `callback_port` of `0` is rejected. Port `None` means 'pick an ephemeral port', but an explicit `Some(0)` is treated as a configuration mistake rather than being silently mapped to ephemeral.
Solutions
- Set the callback port to a concrete value (e.g. 8080–9999) or omit the field entirely to request an ephemeral port
- Fix whatever produced `Some(0)` — replace explicit 0 with `None` in the calling code
- Validate the configured port is in 1..=65535 at config-load time
Example fix
// before callback_port: Some(0) // after callback_port: None // ephemeral port, or Some(8642) for a fixed port
Defensive patterns
Strategy: validation
Validate before calling
if let Some(0) = callback_port {
return Err(anyhow!("callback_port must be 1-65535 or unset"));
} Type guard
fn valid_callback_port(p: Option<u16>) -> Option<u16> {
p.filter(|&p| p != 0)
} Prevention
- Omit callback_port entirely for ephemeral port selection
- Validate configured ports are 1..=65535 when loading config
- Never translate 'auto' to Some(0); use None
When it happens
Trigger: Passing `callback_port: Some(0)` into the OAuth flow constructor (e.g. from a config value of 0 for the MCP OAuth callback port).
Common situations: A config file with `callback_port = 0` intending 'auto-pick'; a port computed by a script that defaulted to 0 on lookup failure.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- MCP server ' ' already has bearer/static Authorization…
- MCP server ' ' not found
- MCP server ' ' was not found.
- McpLoginServerNotFound
- OAuth login is only supported for URL-based MCP servers
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/72ece2bf9d133811.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp/oauth.rs:1588
server_name: String,
server_url: String,
}
impl OauthLoginFlow {
#[allow(clippy::too_many_arguments)]
async fn new(
server_name: &str,
server_url: &str,
client: McpHttpClient,
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 scope_refs: Vec<&str> = scopes.iter().map(String::as_str).collect();
let oauth_state = start_authorization(View on GitHub (pinned to 73e0f67d83)