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
- 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).
- Check the exit code: non-zero exit usually means configuration error; look for 'address already in use' or certificate messages in the output.
- Restart the machine or kill stale dcp processes holding ports, then rerun `aspire doctor`.
- 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
- Always read the recent-output section of the message; it names the true startup failure.
- Kill stale dcp processes and free ports before running doctor.
- Keep DCP binaries and the Aspire CLI versions in sync (aspire update).
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
- Developer Control Plane (DCP) kubeconfig did not contain a…
- Failed to start Developer Control Plane (DCP).
- Could not find DCP executable in the Aspire layout.
- Invalid value " " for "--dcp-dependency-check-timeout"…
- No fully trusted exportable developer certificate with a…
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)