{"record":{"id":"ccfaea67ff880eb7","repo":"microsoft/aspire","slug":"failed-to-start-devtunnel-process","errorCode":null,"errorMessage":"Failed to start devtunnel process.","messagePattern":"Failed to start devtunnel process\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.DevTunnels/DevTunnelCli.cs","lineNumber":255,"sourceCode":"\n    private async Task<int> RunAsync(Action<bool, string> onOutput, string[] args, bool useShellExecute = false, ILogger? logger = default, CancellationToken cancellationToken = default)\n    {\n        using var process = new Process\n        {\n            StartInfo = BuildStartInfo(args, useShellExecute),\n            EnableRaisingEvents = true\n        };\n\n        var stdoutTask = Task.CompletedTask;\n        var stderrTask = Task.CompletedTask;\n\n        logger?.LogTrace(\"Invoking devtunnel CLI{ShellExecuteInfo}: {FileName} {Arguments}\", useShellExecute ? \" (UseShellExecute=true)\" : \"\", process.StartInfo.FileName, EscapeArgList(process.StartInfo.ArgumentList));\n\n        try\n        {\n            if (!process.Start())\n            {\n                throw new InvalidOperationException(\"Failed to start devtunnel process.\");\n            }\n\n            if (!useShellExecute)\n            {\n                stdoutTask = PumpAsync(process.StandardOutput, line => onOutput(false, line), cancellationToken);\n                stderrTask = PumpAsync(process.StandardError, line => onOutput(true, line), cancellationToken);\n            }\n\n            using var ctr = cancellationToken.Register(() =>\n            {\n                try\n                {\n                    if (!process.HasExited)\n                    {\n                        logger?.LogTrace(\"Cancellation requested, killing devtunnel process tree.\");\n                        process.Kill(entireProcessTree: true);\n                    }\n                }","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.DevTunnels/DevTunnelCli.cs#L237-L273","documentation":"DevTunnelCli.RunAsync launches the devtunnel executable and checks the boolean result of Process.Start(). If the operating system fails to spawn the process, the method throws this InvalidOperationException rather than letting the run continue with a dead process handle.","triggerScenarios":"Calling any DevTunnelCli operation (GetVersionAsync, CreateTunnelAsync, etc.) when Process.Start returns false — the executable path exists but the OS cannot spawn it, or the path resolved to a non-executable.","commonSituations":"devtunnel binary not installed or not on PATH so the resolved 'devtunnel' path is invalid; file exists but lacks execute permission (Linux/macOS); antivirus or sandbox blocking process creation; corrupted CLI download.","solutions":["Verify the devtunnel CLI is installed: run 'devtunnel --version' in a terminal","Set ASPIRE_DEVTUNNEL_CLI_PATH to the absolute path of a working devtunnel executable","On Linux/macOS, ensure the binary has the execute bit (chmod +x)","Check antivirus/EDR policies or sandbox restrictions that block spawning the process"],"exampleFix":"// before (appsettings/env)\nASPIRE_DEVTUNNEL_CLI_PATH=devtunnel   // not on PATH\n// after\nASPIRE_DEVTUNNEL_CLI_PATH=/usr/local/bin/devtunnel","handlingStrategy":"try-catch","validationCode":"var resolved = DevTunnelCli.GetCliPath(configuration);\nif (resolved != \"devtunnel\" && !File.Exists(resolved))\n    throw new InvalidOperationException($\"devtunnel CLI not found at '{resolved}'.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    await cli.GetVersionAsync();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Failed to start devtunnel process\"))\n{\n    logger.LogError(ex, \"Could not launch devtunnel CLI at '{Path}'. Verify install and execute permissions.\", cliPath);\n}","preventionTips":["Install the devtunnel CLI and verify with 'devtunnel --version' before starting the AppHost","Pin ASPIRE_DEVTUNNEL_CLI_PATH to an absolute path in CI","Check execute permissions on Linux/macOS after extracting the CLI","Exclude the CLI directory from antivirus/scanner interference"],"tags":["devtunnels","process-start","cli","environment"],"backgroundTag":"command-not-found","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}