zed-industries/zed · error
Socket closed before a message was received
Error message
Socket closed before a message was received
What it means
recv_json() is the JSON-line protocol reader for the ETW Unix socket. read_line() returned zero bytes, which is EOF: the peer closed the socket without writing a status message. In the parent this surfaces (wrapped as 'Wait for Started status') when the elevated recording subprocess connects via accept() but then exits or crashes before/at sending StatusMessage::Started; in the child it occurs when the parent disappears.
Source
Thrown at crates/etw_tracing/etw_tracing.rs:667
#[derive(Debug, serde::Serialize, serde::Deserialize)]
#[serde(tag = "type")]
pub enum Command {
Save,
Cancel,
}
fn send_json<T: serde::Serialize>(writer: &mut impl Write, value: &T) -> Result<()> {
let json = serde_json::to_string(value).context("Serialize message")?;
writeln!(writer, "{json}").context("Write to socket")?;
writer.flush().context("Flush socket")?;
Ok(())
}
fn recv_json<T: serde::de::DeserializeOwned>(reader: &mut impl BufRead) -> Result<T> {
let mut line = String::new();
reader.read_line(&mut line).context("Read from socket")?;
if line.is_empty() {
bail!("Socket closed before a message was received");
}
serde_json::from_str(line.trim()).context("Parse message")
}
View on GitHub (pinned to f4178619ac)
Solutions
- Check the elevated child's logs/stderr - it died before reporting anything; look for panic messages or DLL/load errors in the Zed log
- Re-run the recording once to rule out a transient crash during WPR start
- Verify the Zed exe that gets elevated is intact (std::env::current_exe() is what ShellExecuteW relaunches; a corrupted/half-updated binary dies instantly)
- Exclude/allow the Zed binary in antivirus/EDR if it is killing the elevated child
- If the child is crashing reproducibly in record_etw_trace, report a Zed bug with the panic backtrace
Defensive patterns
Strategy: try-catch
Try / catch
match launch_etw_recording(heap_pid, output_path) {
Ok(session) => Ok(session),
Err(err) if err.to_string().contains("Socket closed before a message was received") => {
// child died silently: check crash logs, offer one retry
check_elevated_child_logs();
retry_once()
}
Err(err) => Err(err),
} Prevention
- Log the elevated child's stderr/panics somewhere the parent can point the user at
- Retry once on EOF - child crashes during WPR startup are occasionally transient
- Distinguish EOF (child said nothing) from Error status (child reported a reason) when triaging
When it happens
Trigger: (1) launch_etw_recording(): elevated Zed child connects, then dies (panic, early exit, crash in WPR/COM before send_json(Started)) leaving the parent to read EOF. (2) receive_command() in the elevated child when the parent process is killed while the child waits for Save/Stop commands (there it is downgraded to a timed-out Save).
Common situations: Elevated child crashing during WPR startup (panic before the first send_json), UAC elevation launching an exe that immediately terminates (e.g. broken install, missing DLLs), the child being killed by antivirus/EDR, or the socket file at %TEMP%/zed-etw-<pid>.sock being removed. Distinguish from error 260: here the child said nothing at all.
Related errors
- Subprocess reported error during start: {message}
- Unexpected status from subprocess: {other:?}
- Failed to set socket receive timeout: setsockopt returned {r
- ShellExecuteW failed to launch elevated process (code: {resu
- Device lost: {err}
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/ceebefe88210f22c.
Report an issue: GitHub.