{"record":{"id":"f5647dacb2d81022","repo":"Kuberwastaken/claurst","slug":"failed-to-bind-oauth-callback-listener-on","errorCode":null,"errorMessage":"Failed to bind OAuth callback listener on {}:{}: {}","messagePattern":"Failed to bind OAuth callback listener on (.+?):(.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-rust/crates/mcp/src/oauth.rs","lineNumber":233,"sourceCode":"    redirect_uri: &str,\n) -> anyhow::Result<(TcpListener, String, String)> {\n    let redirect_url = url::Url::parse(redirect_uri)\n        .map_err(|e| anyhow::anyhow!(\"Failed to parse redirect URI '{}': {}\", redirect_uri, e))?;\n    let host = redirect_url\n        .host_str()\n        .ok_or_else(|| anyhow::anyhow!(\"Redirect URI '{}' is missing host\", redirect_uri))?\n        .to_string();\n    let port = redirect_url\n        .port_or_known_default()\n        .ok_or_else(|| anyhow::anyhow!(\"Redirect URI '{}' is missing port\", redirect_uri))?;\n    let callback_path = if redirect_url.path().is_empty() {\n        \"/callback\".to_string()\n    } else {\n        redirect_url.path().to_string()\n    };\n    let listener = TcpListener::bind((host.as_str(), port))\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to bind OAuth callback listener on {}:{}: {}\", host, port, e))?;\n\n    Ok((listener, host, callback_path))\n}\n\nasync fn wait_for_authorization_code(\n    listener: TcpListener,\n    host: &str,\n    callback_path: &str,\n    expected_state: Option<&str>,\n) -> anyhow::Result<String> {\n    let (mut socket, _) = tokio::time::timeout(Duration::from_secs(180), listener.accept())\n        .await\n        .map_err(|_| anyhow::anyhow!(\"Timeout waiting for OAuth callback\"))?\n        .map_err(|e| anyhow::anyhow!(\"Failed to accept OAuth callback connection: {}\", e))?;\n\n    let (reader, mut writer) = socket.split();\n    let mut reader = BufReader::new(reader);\n    let mut request_line = String::new();","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/mcp/src/oauth.rs#L215-L251","documentation":"The local TCP listener for the OAuth callback could not bind to the host:port derived from the redirect_uri. Typically the port is already in use (another auth session or a stale listener holding it), or the host is not bindable on this machine.","triggerScenarios":"bind_callback_listener on a port already in use, a privileged port (<1024) without root, an unresolvable/blocked host name, or IPv6-only host strings the resolver can't handle.","commonSituations":"Another instance of the tool or a dev server occupies the port (EADDRINUSE); running inside Docker/K8s without the port published; firewall blocking loopback binding of a nonstandard port; registering port 80/443 with the provider and running unprivileged.","solutions":["Free the port or pick another (lsof -i :PORT / netstat) and update both the config and the provider-registered redirect URI","Use a high port (e.g. 49152+) that needs no privileges and is unlikely to collide","Confirm the host resolves — prefer 127.0.0.1 over a hostname","If binding a low port is required, grant cap_net_bind_service rather than running as root"],"exampleFix":"// before\nlet redirect_uri = \"http://127.0.0.1:80/callback\";\n// after\nlet redirect_uri = \"http://127.0.0.1:8090/callback\";","handlingStrategy":"validation","validationCode":"async fn port_free(port: u16) -> bool {\n    tokio::net::TcpListener::bind((\"127.0.0.1\", port)).await.is_ok()\n}","typeGuard":null,"tryCatchPattern":"match bind_callback_listener(&uri).await {\n    Ok((l, h, p)) => { /* proceed */ }\n    Err(e) if e.to_string().contains(\"address already in use\") => eprintln!(\"port busy; pick another\"),\n    Err(e) => eprintln!(\"bind failed: {e}\"),\n}","preventionTips":["Check the port is free before starting the flow (lsof -i :PORT)","Use high, uncommon ports","Avoid privileged ports <1024 unless running with capabilities","Update the provider-registered redirect whenever you change ports"],"tags":["network","bind","oauth"],"backgroundTag":"address-already-in-use","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}