microsoft/aspire · error · InvalidOperationException

Failed to start Aspire dashboard

Error message

Failed to start Aspire dashboard: {0}

What it means

After resolving the dashboard binary, ProfileCaptureService.StartAsync launches aspire-managed (the dashboard process) with killOnParentExit enabled. Any exception thrown while starting that process — including Win32 spawn failures, missing-file errors, or runner-level failures — is caught and rethrown as this InvalidOperationException, wrapping the original message. The bundle layout lease is disposed before rethrowing.

Solutions

  1. Inspect the inner exception message (appended after 'Failed to start Aspire dashboard:') to find the root cause.
  2. Run 'aspire setup --force' or reinstall the CLI to repair a corrupted aspire-managed binary.
  3. Check that the configured DashboardUrl/Otlp URLs are well-formed and their ports are free.
  4. Verify antivirus/EDR policies allow executing the aspire-managed binary.
  5. Retry the profiling capture once; transient spawn failures do occur.

Example fix

// before: invalid URL config causing spawn arg failure
--urls=http://:notaport
// after: valid loopback URL with ephemeral port
--urls=http://127.0.0.1:0
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    var session = await captureService.StartAsync(options, ct);
}
catch (InvalidOperationException ex)
{
    // Inner message appended after 'Failed to start Aspire dashboard:' names the root cause.
    logger.LogError(ex, "Dashboard spawn failed: {Reason}", ex.InnerException?.Message);
}

Prevention

When it happens

Trigger: Calling ProfileCaptureService.StartAsync where layoutProcessRunner.StartAsync for aspire-managed throws: binary cannot be created as a process (CreateProcess failure), environment-variable setup fails, port binding configuration is invalid, or an underlying WindowsProcessInterop error (211-214) surfaces.

Common situations: Antivirus blocking aspire-managed execution; corrupted executable after partial extraction; invalid dashboard/OTLP URL configuration making the process arguments invalid; OS-level process-creation restrictions in hardened environments; low resource conditions preventing spawn.

Related errors


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

Appendix: source

Thrown at src/Aspire.Cli/Profiling/ProfileCaptureService.cs:120

            var environmentVariables = CreateDashboardEnvironment();
            layoutLease?.AddEnvironment(environmentVariables);

            // Launch aspire-managed directly instead of calling `aspire dashboard run`. Calling
            // back through the CLI being profiled would recursively apply --capture-profile and
            // make the collector part of the measurement.
            // Bind the collector dashboard to the Windows kill-on-close job so it cannot outlive a
            // hard-killed CLI (OS-level backstop on top of the cross-platform watchdog). No-op off Windows.
            dashboardProcess = await layoutProcessRunner.StartAsync(
                managedPath,
                dashboardArgs,
                environmentVariables: environmentVariables,
                options: processOptions,
                killOnParentExit: true).ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            layoutLease?.Dispose();
            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, DashboardCommandStrings.DashboardFailedToStart, ex.Message), ex);
        }

        var session = new ProfileCaptureSession(
            options,
            dashboardProcess,
            httpClientFactory,
            interactionService,
            timeProvider,
            logger,
            s_profileDataTimeout,
            s_pollInterval,
            ProfileDataQuietPolls,
            layoutLease);
        try
        {
            await session.WaitForDashboardAsync(dashboardStartTimeout, pollInterval, cancellationToken).ConfigureAwait(false);
            return session;
        }

View on GitHub (pinned to 25830f84bd)