zed-industries/zed · warning

Timed out pinging remote client

Error message

Timed out pinging remote client

What it means

The heartbeat path sends a proto::Ping RPC and races it against an executor timer (crates/remote/src/remote_client.rs:1933). If the ping round-trip exceeds the timeout, this error fires; repeated occurrences count as missed heartbeats and eventually trigger reconnect or disconnect.

Source

Thrown at crates/remote/src/remote_client.rs:1954

                for envelope in self.buffer.lock().iter() {
                    self.outgoing_tx
                        .lock()
                        .unbounded_send(envelope.clone())
                        .ok();
                }
                Ok(())
            },
            async {
                self.executor.timer(timeout).await;
                anyhow::bail!("Timed out resyncing remote client")
            },
        )
        .await
    }

    async fn ping(&self, timeout: Duration) -> Result<()> {
        smol::future::or(
            async {
                self.request(proto::Ping {}).await?;
                Ok(())
            },
            async {
                self.executor.timer(timeout).await;
                anyhow::bail!("Timed out pinging remote client")
            },
        )
        .await
    }

    fn send<T: EnvelopedMessage>(&self, payload: T) -> Result<()> {
        log::debug!("remote send name:{}", T::NAME);
        self.send_dynamic(payload.into_envelope(0, None, None))
    }

    fn request_dynamic(

View on GitHub (pinned to 5a9b9558db)

Solutions

  1. Treat it as transient: the client's heartbeat logic re-pings and reconnects if needed
  2. If pings time out repeatedly, check remote host load (top/htop over SSH)
  3. For suspended clients, expect an automatic reconnect after resume rather than a code fix
Defensive patterns

Strategy: retry

Try / catch

match client.ping(timeout).await {
    Err(e) if e.to_string().contains("Timed out pinging") => {
        // transient: re-ping once with a longer timeout before giving up
        client.ping(timeout * 2).await
    }
    other => other,
}

Prevention

When it happens

Trigger: A proto::Ping request is not answered within the timeout Duration - unresponsive or GC-paused remote server, saturated link, or a suspended client machine mid-session.

Common situations: Remote host under heavy load; laptop waking from suspend; networks that black-hole TCP instead of resetting it.

Understand the failure class

Related errors


AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20). Data as JSON: /api/errors/6ef2c10436f42a53. Report an issue: GitHub.