microsoft/aspire · error · InvalidOperationException
Failed to start DCP fork-process.
Error message
Failed to start DCP fork-process.
What it means
After building the DCP ProcessStartInfo, StartDetachedUnixAsync calls Process.Start and throws if the OS returns null, meaning the DCP fork-process could not be launched at all. This indicates a pre-exec failure (bad path, missing binary, exec permissions) rather than a runtime error from DCP itself.
Solutions
- Verify the DCP path exists and is executable (ls -l $path; chmod +x $path).
- Reinstall/repair the Aspire CLI to restore a complete DCP binary for your platform/arch.
- Run the DCP binary directly in a terminal to see the OS-level error.
- Check CPU architecture matches the binary (file $path on Linux/macOS).
Example fix
// before: launcher binary present but not executable
// after
chmod +x /path/to/dcp
var dcpProcess = Process.Start(dcpStartInfo)
?? throw new InvalidOperationException("Failed to start DCP fork-process."); Defensive patterns
Strategy: validation
Validate before calling
var path = startInfo.DetachedUnixLauncherPath!;
if (!File.Exists(path)) throw new FileNotFoundException("DCP launcher not found", path);
if (!(File.GetUnixFileMode(path) & UnixFileMode.Execute).HasFlag(UnixFileMode.Execute))
throw new UnauthorizedAccessException($"DCP launcher is not executable: {path}"); Try / catch
try
{
await process.StartAsync(ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Failed to start DCP fork-process"))
{
// check launcher exists, is executable, and matches the machine architecture
} Prevention
- Verify the DCP binary exists and is +x after each install/upgrade
- Confirm the binary matches OS and CPU architecture
- Reinstall the CLI if the DCP binary looks truncated
When it happens
Trigger: Process.Start(dcpStartInfo) returns null during StartAsync's detached Unix launch: DetachedUnixLauncherPath points to a nonexistent, non-executable, or incompatible (wrong arch/OS) binary.
Common situations: A truncated or partially extracted DCP binary after an interrupted install; wrong-architecture binary (arm64 vs x64); file lacks +x permission; path corrupted after an upgrade.
Related errors
- DCP fork-process did not return a child process ID. DCP…
- DCP fork-process did not return a valid child process ID…
- Unix detached process launch requires a DCP executable path.
- Could not determine the identity timestamp for monitor…
- Could not find DCP executable in the Aspire layout.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/408d1638add2cf4c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Cli/Processes/IsolatedProcess.Unix.cs:48
dcpStartInfo.ArgumentList.Add("fork-process");
dcpStartInfo.ArgumentList.Add("--monitor");
dcpStartInfo.ArgumentList.Add(Environment.ProcessId.ToString(CultureInfo.InvariantCulture));
dcpStartInfo.ArgumentList.Add("--monitor-identity-time");
dcpStartInfo.ArgumentList.Add(ProcessTreeGracefulShutdownService.FormatDcpProcessStartTime(GetCurrentProcessDcpMonitorStartTime()));
dcpStartInfo.ArgumentList.Add("--");
dcpStartInfo.ArgumentList.Add(startInfo.FileName);
foreach (var arg in startInfo.ArgumentList)
{
dcpStartInfo.ArgumentList.Add(arg);
}
ProcessEnvironment.ApplyTo(dcpStartInfo, startInfo.GetEnvironmentForSpawn());
cancellationToken.ThrowIfCancellationRequested();
var dcpProcess = Process.Start(dcpStartInfo)
?? throw new InvalidOperationException("Failed to start DCP fork-process.");
var stderrTask = dcpProcess.StandardError.ReadToEndAsync(CancellationToken.None);
var stdoutLineTask = dcpProcess.StandardOutput.ReadLineAsync(CancellationToken.None).AsTask();
try
{
// Once DCP has started, wait for it to report the detached child PID even if the caller
// cancels. Without the PID, callers cannot clean up a child that was already forked.
var stdoutLine = await stdoutLineTask.ConfigureAwait(false);
if (stdoutLine is null)
{
await dcpProcess.WaitForExitAsync(CancellationToken.None).ConfigureAwait(false);
var stderr = await stderrTask.ConfigureAwait(false);
throw new InvalidOperationException($"DCP fork-process did not return a child process ID. DCP fork-process exited with code {dcpProcess.ExitCode}. stderr: '{stderr.Trim()}'");
}
var trimmedStdout = stdoutLine.Trim();
// DCP fork-process writes only the detached child PID followed by a newline, for example:View on GitHub (pinned to 25830f84bd)