microsoft/aspire · error · InvalidOperationException

Developer Control Plane (DCP) kubeconfig did not contain a…

Error message

Developer Control Plane (DCP) kubeconfig did not contain a valid server URI.

What it means

DcpKubeconfig.Parse reads the kubeconfig file DCP writes and extracts the cluster server URL, token, and client credentials. If the parsed `server` field is missing/blank or not an absolute URI, Parse throws InvalidOperationException indicating the kubeconfig contains no valid server URI - meaning the file is structurally present but the connection endpoint could not be determined.

Solutions

  1. Retry the operation - the checker already retries reads; a fresh DCP start usually writes a complete kubeconfig.
  2. Delete the stale kubeconfig file/session directory and rerun `aspire doctor` so DCP regenerates it.
  3. Open the kubeconfig file and inspect the `server:` line; if empty/malformed, this indicates a DCP startup problem - check DCP output for errors.
  4. Reinstall/update DCP if it consistently writes invalid kubeconfigs.

Example fix

// consumer-side retry around doctor's DCP check
try
{
    var kubeconfig = await DcpKubeconfig.ReadFileWithRetryAsync(path, ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("server URI"))
{
    File.Delete(path); // discard partial kubeconfig
    Console.Error.WriteLine("DCP wrote an invalid kubeconfig; restarting DCP check...");
}
Defensive patterns

Strategy: retry

Validate before calling

var text = File.ReadAllText(kubeconfigPath);
var serverLine = text.Split('\n').FirstOrDefault(l => l.TrimStart().StartsWith("server:"));
var serverValue = serverLine?.Split(':', 2)[1].Trim().Trim('"');
bool valid = !string.IsNullOrWhiteSpace(serverValue) && Uri.TryCreate(serverValue, UriKind.Absolute, out _);

Type guard

static bool TryGetServerUri(string kubeconfigText, out Uri? uri) { var line = kubeconfigText.Split('\n').FirstOrDefault(l => l.TrimStart().StartsWith("server:")); var v = line?.Split(':', 2)[1].Trim().Trim('"'); return v is not null && Uri.TryCreate(v, UriKind.Absolute, out uri); }

Try / catch

try { var kc = await DcpKubeconfig.ReadFileWithRetryAsync(path, ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("server URI")) { File.Delete(path); await RestartDcpAndRetryAsync(); }

Prevention

When it happens

Trigger: ReadFileWithRetryAsync successfully reads the DCP-written kubeconfig but the parsed server line is absent, empty, or malformed (e.g. DCP wrote a partial/empty kubeconfig, or the server value is not a valid absolute URL) causing Uri.TryCreate to fail.

Common situations: DCP writing a truncated kubeconfig during startup (file observed before fully flushed), a race where the checker read the file mid-write, corrupted previous kubeconfig content, or DCP misconfiguration emitting an empty server address.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Cli/Utils/EnvironmentChecker/DcpKubeconfig.cs:75

        //   users:
        //   - name: dcp
        //     user:
        //       client-certificate-data: <base64 PEM>
        //       client-key-data: <base64 PEM>
        // The doctor probe only needs connection material, so parse the scalar fields directly
        // instead of adding a YAML dependency to the NativeAOT CLI.
        foreach (var line in content.Split('\n'))
        {
            server ??= TryReadScalar(line, "server");
            token ??= TryReadScalar(line, "token");
            certificateAuthorityData ??= TryReadScalar(line, "certificate-authority-data");
            clientCertificateData ??= TryReadScalar(line, "client-certificate-data");
            clientKeyData ??= TryReadScalar(line, "client-key-data");
        }

        if (string.IsNullOrWhiteSpace(server) || !Uri.TryCreate(server, UriKind.Absolute, out var serverUri))
        {
            throw new InvalidOperationException(DoctorCommandStrings.DcpKubeconfigMissingServerDetails);
        }

        return new DcpKubeconfig
        {
            Server = serverUri,
            Token = token,
            CertificateAuthorityCertificates = certificateAuthorityData is null
                ? []
                : LoadCertificates(certificateAuthorityData),
            ClientCertificate = clientCertificateData is not null && clientKeyData is not null
                ? LoadClientCertificate(clientCertificateData, clientKeyData)
                : null
        };
    }

    public void Dispose()
    {
        foreach (var certificate in CertificateAuthorityCertificates)

View on GitHub (pinned to 25830f84bd)