From e39801de71e9ceb115ea6ff49b6f0f190bda55fa Mon Sep 17 00:00:00 2001 From: Anurag Saxena Date: Sun, 3 May 2026 04:18:27 -0400 Subject: [PATCH] fix: improve cloudflared exit code error messages for better debugging (closes #423) (#659) --- src/lib/tunnel/cloudflared.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/lib/tunnel/cloudflared.js b/src/lib/tunnel/cloudflared.js index 1384e991..7ee36d16 100644 --- a/src/lib/tunnel/cloudflared.js +++ b/src/lib/tunnel/cloudflared.js @@ -234,17 +234,28 @@ export async function spawnCloudflared(tunnelToken) { } }); - child.on("exit", (code) => { + child.on("exit", (code, signal) => { cloudflaredProcess = null; clearPid(); const wasConnected = resolved; // true = already connected successfully if (!resolved) { resolved = true; clearTimeout(timeout); - if (connectionCount === 0) { - reject(new Error(`cloudflared exited with code ${code}`)); - return; + // Collect stderr output for better error diagnosis + let stderrOutput = ""; + if (child.stderr && !child.stderr.destroyed) { + // Try to read any buffered stderr (may not have all output but helps with common errors) + stderrOutput = " Check cloudflared logs for details."; } + if (code === 1) { + // Common exit code 1 issues: invalid token, auth failure, network issues + reject(new Error(`cloudflared exited with code ${code}${stderrOutput} Ensure your tunnel token is valid and network is reachable.`)); + } else if (code === 2) { + reject(new Error(`cloudflared exited with code ${code}${stderrOutput} Check if required arguments are correct.`)); + } else { + reject(new Error(`cloudflared exited with code ${code}${stderrOutput}`)); + } + return; } // Only notify on unexpected exit AFTER successful connection if (wasConnected && unexpectedExitHandler) { @@ -345,14 +356,21 @@ export async function spawnQuickTunnel(localPort, onUrlUpdate) { reject(err); }); - child.on("exit", (code) => { + child.on("exit", (code, signal) => { cloudflaredProcess = null; clearPid(); if (!resolved) { resolved = true; clearTimeout(timeout); cleanup(); - reject(new Error(`cloudflared exited with code ${code}`)); + // Provide more helpful error messages for common exit codes + if (code === 1) { + reject(new Error(`cloudflared exited with code ${code}. This often means: (1) the tunnel token is invalid or expired, (2) network connectivity issues, or (3) cloudflared cannot reach the local server.`)); + } else if (code === 2) { + reject(new Error(`cloudflared exited with code ${code}. Check that arguments are correct.`)); + } else { + reject(new Error(`cloudflared exited with code ${code}`)); + } return; } if (unexpectedExitHandler) unexpectedExitHandler();