jlcodes99/cockpit-tools · error

本地回调服务异常: {}

Error message

本地回调服务异常: {}

What it means

Logged during restore_pending_oauth_listener when re-creating the Kiro OAuth local HTTP callback server (for a pending login identified by login_id/state) fails. The error is stored as the callback result for that login, so any client waiting on the login future receives "本地回调服务异常: {reason}" instead of tokens.

Source

Thrown at crates/cockpit-core/src/modules/kiro_oauth.rs:134

    if state.callback_result.is_some() {
        return;
    }

    match TcpListener::bind(("127.0.0.1", state.callback_port)) {
        Ok(listener) => {
            drop(listener);
            let expected_login_id = state.login_id.clone();
            let expected_state = state.state_token.clone();
            let callback_port = state.callback_port;
            tokio::spawn(async move {
                if let Err(err) = start_callback_server(
                    callback_port,
                    expected_login_id.clone(),
                    expected_state.clone(),
                )
                .await
                {
                    logger::log_error(&format!(
                        "[Kiro OAuth] 回调服务恢复失败: login_id={}, error={}",
                        expected_login_id, err
                    ));
                    set_callback_result_for_login(
                        &expected_login_id,
                        &expected_state,
                        Err(format!("本地回调服务异常: {}", err)),
                    );
                }
            });
            logger::log_info(&format!(
                "[Kiro OAuth] 已恢复本地回调服务: login_id={}, port={}",
                state.login_id, state.callback_port
            ));
        }
        Err(err) if err.kind() == ErrorKind::AddrInUse => {
            logger::log_info(&format!(
                "[Kiro OAuth] 本地回调端口已占用,视为监听中: login_id={}, port={}",

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Free the configured callback_port (find and kill the process listening on it, e.g. `lsof -i :PORT`).
  2. Cancel the stale pending login and start a fresh Kiro OAuth login instead of restoring the old one.
  3. Configure a different, unprivileged callback port (>1024) in settings.
  4. Check firewall/antivirus policies that may prevent binding a local listener.
  5. Retry after ensuring no duplicate app instance is running.

Example fix

// before: blindly reusing the fixed callback port
let port = 17850;
// after: detect a busy port before starting login
fn port_free(p: u16) -> bool { std::net::TcpListener::bind(("127.0.0.1", p)).is_ok() }
let port = if port_free(17850) { 17850 } else { pick_free_port() };
Defensive patterns

Strategy: validation

Validate before calling

// Check the callback port is bindable before restoring a pending login
fn callback_port_free(port: u16) -> bool {
    std::net::TcpListener::bind(("127.0.0.1", port)).is_ok()
}
if !callback_port_free(callback_port) {
    return Err(format!("callback port {} occupied; free it or pick another", callback_port));
}

Type guard

fn is_callback_server_error(err: &str) -> bool {
    err.starts_with("本地回调服务异常: ")
}

Try / catch

match restore_pending_oauth_listener(&login_id, &state).await {
    Err(err) if is_callback_server_error(&err) => {
        cancel_pending_login(&login_id);
        ui.prompt("本地回调端口被占用,请释放端口后重新登录");
    }
    other => handle(other),
}

Prevention

When it happens

Trigger: Calling start_login or restore_pending_oauth_listener where a previous pending OAuth flow exists and start_callback_server_for_state cannot bind the callback_port (address already in use, permission denied) or fails while initializing the listener.

Common situations: Port already occupied by a previous crashed/zombie listener or another app; firewall blocking local binding; app restarted mid-login leaving a stale pending state that cannot be restored; privileged/low port configured; SELinux/security software blocking socket bind.

Related errors


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/bdfed8df05ebdf8a. Report an issue: GitHub.