zed-industries/zed · error

Timed out when connecting to debugger

Error message

Timed out when connecting to debugger

What it means

In TransportDelegate's connection loop, receive_server_message returned ConnectionResult::Timeout - no complete DAP message arrived from the adapter's stdout within the receive timeout window - so Zed gives up with 'Timed out when connecting to debugger'. The TCP socket/stdout may be open, but the adapter never spoke DAP when expected.

Source

Thrown at crates/dap/src/transport.rs:345

    async fn recv_from_server<Stdout>(
        server_stdout: Stdout,
        mut message_handler: DapMessageHandler,
        pending_requests: Arc<Mutex<PendingRequests>>,
        log_handlers: Option<LogHandlers>,
    ) -> Result<()>
    where
        Stdout: AsyncRead + Unpin + Send + 'static,
    {
        let mut recv_buffer = String::new();
        let mut reader = BufReader::new(server_stdout);

        let result = loop {
            let result =
                Self::receive_server_message(&mut reader, &mut recv_buffer, log_handlers.as_ref())
                    .await;
            match result {
                ConnectionResult::Timeout => anyhow::bail!("Timed out when connecting to debugger"),
                ConnectionResult::ConnectionReset => {
                    log::info!("Debugger closed the connection");
                    return Ok(());
                }
                ConnectionResult::Result(Ok(Message::Response(res))) => {
                    let tx = pending_requests.lock().remove(res.request_seq)?;
                    if let Some(tx) = tx {
                        if let Err(e) = tx.send(Self::process_response(res)) {
                            log::trace!("Did not send response `{:?}` for a cancelled", e);
                        }
                    } else {
                        message_handler(Message::Response(res))
                    }
                }
                ConnectionResult::Result(Ok(message)) => message_handler(message),
                ConnectionResult::Result(Err(e)) => break Err(e),
            }
        };

View on GitHub (pinned to f4178619ac)

Solutions

  1. Run the adapter binary manually with the same arguments and confirm it emits DAP framing on stdout promptly
  2. Remove interactive prompts / heavy init scripts (e.g. .lldbinit, gdb auto-load) from adapter startup
  3. Ensure wrapper scripts do not write anything to stdout - route chatter to stderr
  4. Increase the connection timeout if the adapter legitimately needs longer to start
Defensive patterns

Strategy: retry

Validate before calling

// Smoke-test the adapter before wiring it into a session
let output = util::command::new_std_command(adapter_path)
    .arg("--version")
    .output()
    .await?;
anyhow::ensure!(output.status.success(), "adapter failed smoke test");

Try / catch

match start_session(/* .. */).await {
    Ok(session) => Ok(session),
    Err(err) if err.to_string().contains("Timed out when connecting") => {
        // one retry with a longer timeout; then surface adapter stdout logs
        retry_with_longer_timeout().await
    }
    Err(err) => Err(err),
}

Prevention

When it happens

Trigger: Starting a debug session where the adapter process launches but never writes its initialize response: adapter hanging on startup (first-run downloads, license prompts), adapter printing non-DAP noise to stdout so framing never matches, extremely slow cold start exceeding the timeout, or the adapter crashing before its first output.

Common situations: First launch of a freshly-installed adapter that downloads components; debuggers that prompt interactively (lldb init scripts, license checks); stdout polluted by wrapper scripts (npx, shell echo); overloaded CI machines making startup exceed the fixed window.

Understand the failure class

Related errors


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/09b772200ba35f08. Report an issue: GitHub.