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

  1. Ensure the control-socket supervisor is started and listening before launching deno, and that the address in DENO_UNSTABLE_CONTROL_SOCK matches exactly
  2. 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`
  3. 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

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


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/714ca7fb78a0922b. Report an issue: GitHub.