microsoft/aspire · error · InvalidOperationException

Developer Control Plane (DCP) exited before writing…

Error message

Developer Control Plane (DCP) exited before writing kubeconfig. Exit code: {0}.{1}{2}.

What it means

After starting the DCP server, the checker waits for DCP to write its kubeconfig file. If the process exits before that file appears, WaitForKubeconfigFileAsync throws InvalidOperationException including the process exit code and recent stdout/stderr output, so the actual startup failure (bad flags, port conflicts, crash) is visible.

Solutions

  1. Read the recent DCP output included in the exception message - it names the real startup error; fix that underlying cause (port conflict, bad flag, cert error).
  2. Check the exit code: non-zero exit usually means configuration error; look for 'address already in use' or certificate messages in the output.
  3. Restart the machine or kill stale dcp processes holding ports, then rerun `aspire doctor`.
  4. Reinstall/update DCP via the Aspire CLI if binaries appear corrupt or version-mismatched.

Example fix

// run doctor and surface the detail
try
{
    await checker.CheckAsync(options);
}
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Developer Control Plane (DCP) exited"))
{
    Console.Error.WriteLine(ex.Message); // includes exit code + recent output
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (File.Exists(kubeconfigPath)) { /* pre-existing kubeconfig from a prior run may mask failures - clear sessions before starting */ Directory.Delete(sessionDirectory, recursive: true); }

Try / catch

try { var session = await checker.CheckAsync(options); }
catch (InvalidOperationException ex) when (ex.Message.Contains("exited before writing kubeconfig")) { Console.Error.WriteLine(ex.Message); /* message already includes exit code + recent DCP output */ }

Prevention

When it happens

Trigger: DcpConnectionChecker session's WaitForKubeconfigFileAsync polling loop observes _process.HasExited == true while the kubeconfig path does not exist - DCP crashed at startup, exited with an argument/configuration error, or was killed before writing kubeconfig.

Common situations: DCP failing due to an invalid TLS/developer certificate being passed, port already in use, corrupted DCP installation, incompatible Kubernetes-style flags, or the process being terminated by security software shortly after launch.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/93a1cbfd7e054920. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Cli/Utils/EnvironmentChecker/DcpConnectionChecker.cs:387

                try
                {
                    Directory.Delete(_sessionDirectory, recursive: true);
                }
                catch (Exception ex)
                {
                    _logger.LogDebug(ex, "Failed to delete DCP doctor session directory '{SessionDirectory}'.", _sessionDirectory);
                }
            }
        }

        private async Task WaitForKubeconfigFileAsync(CancellationToken cancellationToken)
        {
            while (!File.Exists(_kubeconfigPath))
            {
                if (_process.HasExited)
                {
                    throw new InvalidOperationException(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            DoctorCommandStrings.DcpExitedBeforeKubeconfigDetailsFormat,
                            _process.ExitCode,
                            Environment.NewLine,
                            GetRecentOutput(_output)));
                }

                await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken).ConfigureAwait(false);
            }
        }

        private static string GetRecentOutput(OutputCollector output)
        {
            var lines = output.GetLines()
                .TakeLast(40)
                .Select(line => $"{line.Stream}: {line.Line}")
                .ToArray();

View on GitHub (pinned to 25830f84bd)