decolua/9router · warning

[Tunnel] cloudflared exited unexpectedly, scheduling respawn

Error message

[Tunnel] cloudflared exited unexpectedly, scheduling respawn

What it means

During enableTunnel, the manager registers an unexpected-exit handler BEFORE spawning cloudflared so that even a crash-on-startup triggers it. When the spawned cloudflared process exits without being asked to stop, this warning is logged and the registered onUnexpectedExit callback schedules a respawn of the tunnel. It means the tunnel process died and automatic recovery is underway.

Source

Thrown at src/lib/tunnel/cloudflare/manager.js:76

    killCloudflared(localPort);
    console.log("[Tunnel] killed existing cloudflared");
    throwIfCancelled(token);

    const existing = loadState();
    const shortId = existing?.shortId || generateShortId();

    const onUrlUpdate = async (url) => {
      if (token.cancelled) return;
      console.log(`[Tunnel] url updated: ${url}`);
      await registerTunnelUrl(shortId, url);
      saveState({ shortId, tunnelUrl: url });
      await updateSettings({ tunnelEnabled: true, tunnelUrl: url });
    };

    // Register exit handler BEFORE spawn so it fires even on early exit
    setUnexpectedExitHandler(() => {
      console.warn("[Tunnel] cloudflared exited unexpectedly, scheduling respawn");
      if (onUnexpectedExit) onUnexpectedExit();
    });

    const { tunnelUrl } = await spawnQuickTunnel(localPort, onUrlUpdate);
    console.log(`[Tunnel] spawned: ${tunnelUrl}`);
    throwIfCancelled(token);

    const publicUrl = `https://r${shortId}.abc-tunnel.us`;
    await registerTunnelUrl(shortId, tunnelUrl);
    saveState({ shortId, tunnelUrl });
    await updateSettings({ tunnelEnabled: true, tunnelUrl });
    console.log(`[Tunnel] registered shortId=${shortId} publicUrl=${publicUrl}`);

    // Verify publicUrl first (worker route is reliable; direct *.trycloudflare.com DNS may lag)
    await waitForHealth(publicUrl, token);
    console.log("[Tunnel] public URL healthy");
    // Direct tunnel probe is best-effort: DNS for *.trycloudflare.com can be slow/blocked
    if (!(await probeUrlAlive(tunnelUrl))) {

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Wait — the handler schedules a respawn automatically; verify a new '[Tunnel] spawned: <url>' line follows.
  2. Verify the cloudflared binary exists and is executable (and matches OS/arch); reinstall if needed.
  3. Check outbound network/VPN/firewall to Cloudflare edge (trycloudflare.com) and retry enabling the tunnel.
  4. Ensure no other process manages/kills cloudflared (duplicate tray/daemon instances) and that the local port is not occupied.

Example fix

// before: cloudflared not on PATH → spawn exits instantly, respawn loop
const { tunnelUrl } = await spawnQuickTunnel(localPort, onUrlUpdate);
// after: pre-check binary before enabling
if (!spawnSync("cloudflared", ["--version"], { stdio: "ignore" }).error) {
  const { tunnelUrl } = await spawnQuickTunnel(localPort, onUrlUpdate);
}
Defensive patterns

Strategy: retry

Validate before calling

// ensure cloudflared is available before enabling the tunnel
import { spawnSync } from "child_process";
const check = spawnSync("cloudflared", ["--version"], { stdio: "ignore" });
if (check.error) throw new Error("cloudflared not installed or not on PATH");

Try / catch

// tolerate transient exits; rely on auto-respawn, alert only on repeated failures
let respawnCount = 0;
setUnexpectedExitHandler(() => {
  if (++respawnCount > 5) console.error("[Tunnel] repeated cloudflared crashes — check binary/network");
});

Prevention

When it happens

Trigger: cloudflared terminates on its own during or after spawnQuickTunnel: binary missing/corrupt, network dropped, Cloudflare edge connection closed, port conflict, OOM kill, or early-exit due to bad flags. Also fires after an external 'taskkill cloudflared' or systemd/launchd interference.

Common situations: Laptops sleeping/waking and killing the process; corporate firewalls blocking Cloudflare egress; cloudflared not installed or wrong arch binary; running multiple instances fighting over cloudflared; VPN dropping mid-session.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/554bc40d08ddf160. Report an issue: GitHub.