denoland/deno · error
Failure from control sock: {e}
Error message
Failure from control sock: {e} What it means
Runtime panic in cli/lib.rs main(). When the experimental DENO_UNSTABLE_CONTROL_SOCK env var is set, deno connects to a control socket (unix socket or vsock) and waits for start instructions (runtime config, args, cwd) from a supervisor before booting. If the socket future returns an error — connection refused, peer closed, bad handshake — deno panics with the io error appended.
Source
Thrown at cli/lib.rs:910
let args: Vec<_> = env::args_os().collect();
// If we were invoked through a `node` shim (a symlink/hardlink named `node`
// pointing at this binary), translate the Node.js CLI args to Deno args.
// Done here, before any threads are spawned, because it may set env vars.
let args = node_compat_shim::maybe_rewrite_node_arg0(args);
let future = async move {
let roots = LibWorkerFactoryRoots::default();
#[cfg(unix)]
let (waited_unconfigured_runtime, waited_args, waited_cwd) =
match wait_for_start(&args, roots.clone()) {
Some(f) => match f.await {
Ok(v) => match v {
Some((u, a, c)) => (Some(u), Some(a), Some(c)),
None => (None, None, None),
},
Err(e) => {
panic!("Failure from control sock: {e}");
}
},
None => (None, None, None),
};
#[cfg(not(unix))]
let (waited_unconfigured_runtime, waited_args, waited_cwd) =
(None, None, None);
let args = waited_args.unwrap_or(args);
#[allow(
clippy::disallowed_methods,
reason = "ok because initialization of cwd"
)]
let initial_cwd =
waited_cwd
.map(Some)
.unwrap_or_else(|| match std::env::current_dir() {View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Ensure the control-socket supervisor is started and listening before launching deno, and that the address in DENO_UNSTABLE_CONTROL_SOCK matches exactly
- If you did not intend to use this experimental feature, unset the variable and relaunch: `env -u DENO_UNSTABLE_CONTROL_SOCK deno run script.ts`
- Remove stale socket files and confirm the supervisor writes correct handshake frames (the panic message contains the exact io error)
Example fix
# before DENO_UNSTABLE_CONTROL_SOCK=/tmp/deno.sock deno run app.ts # no listener # after my-supervisor --sock /tmp/deno.sock & DENO_UNSTABLE_CONTROL_SOCK=/tmp/deno.sock deno run app.ts
Defensive patterns
Strategy: validation
Validate before calling
# only pass the env var when the supervisor socket exists and accepts connections
if [ -n "${DENO_UNSTABLE_CONTROL_SOCK:-}" ]; then
[ -S "$DENO_UNSTABLE_CONTROL_SOCK" ] || { echo 'control sock missing'; exit 2; }
(exec 3<>"$DENO_UNSTABLE_CONTROL_SOCK") || { echo 'control sock not connectable'; exit 2; }
fi Prevention
- Launch the supervisor first and probe the socket before spawning deno with the env var
- Never leave DENO_UNSTABLE_CONTROL_SOCK exported globally; pass it per-process
- Treat the control-sock launcher as experimental: pin exact supervisor and deno versions together
When it happens
Trigger: Launching deno with DENO_UNSTABLE_CONTROL_SOCK=<addr> where no supervisor is listening, the socket path is wrong, the supervisor dies mid-handshake, or the vsock/unix socket read/write fails. Unix only.
Common situations: Experimenting with the unstable control-socket launcher feature without a matching supervisor process; a supervisor crash leaving orphaned deno children holding the env var; stale socket files from a previous run.
Related errors
- invalid vsock addr
- invalid control sock
- Socket is not a TCP socket - only TCP connections can be upg
- Invalid port: ''
- EINVAL
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/714ca7fb78a0922b.
Report an issue: GitHub.