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
- Run the adapter binary manually with the same arguments and confirm it emits DAP framing on stdout promptly
- Remove interactive prompts / heavy init scripts (e.g. .lldbinit, gdb auto-load) from adapter startup
- Ensure wrapper scripts do not write anything to stdout - route chatter to stderr
- 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
- Keep adapter stdout pristine - all diagnostics go to stderr or log handlers
- Disable interactive startup (lldbinit, license prompts) in adapter arguments
- Pre-download adapter components so first-launch cold start fits the timeout
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Connection to TCP DAP timeout {address}
- Request failed: {}
- Received error response from adapter. Response: {:?}
- {output} error: process exited before debugger attached.
- When using the `stdio` transport, the path to a debug adapte
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/09b772200ba35f08.
Report an issue: GitHub.