microsoft/aspire · error · DcpDeveloperCertificateUnavailableException

The developer certificate could not be cached because the…

Error message

The developer certificate could not be cached because the user profile directory could not be determined.

What it means

The developer-certificate cache writes the exported cert under CertificateHelpers.AspireDevCertsHttpsCacheDirectory, which is derived from the user profile / home directory. If that base path cannot be resolved to a fully-qualified path (e.g. HOME/USERPROFILE unset or empty), EnsureDeveloperCertificateCache throws DcpDeveloperCertificateUnavailableException because there is nowhere valid to cache the certificate.

Solutions

  1. Ensure HOME (Linux/macOS) or USERPROFILE (Windows) is set to a writable directory before running the Aspire CLI.
  2. In containers, run as a user with a defined home (e.g. `docker run -e HOME=/root ...`) or add `-e HOME=$(mktemp -d)`.
  3. If using sudo, preserve the environment (`sudo -E`) or set HOME explicitly.
  4. Create the account's home directory if the user account exists without one, then rerun the command.

Example fix

// before (container entrypoint)
aspire doctor
// after
export HOME=${HOME:-/root}
mkdir -p "$HOME"
aspire doctor
Defensive patterns

Strategy: validation

Validate before calling

var home = OperatingSystem.IsWindows() ? Environment.GetEnvironmentVariable("USERPROFILE") : Environment.GetEnvironmentVariable("HOME");
if (string.IsNullOrWhiteSpace(home) || !Directory.Exists(home))
    Console.WriteLine("User profile directory missing; set HOME/USERPROFILE before running aspire.");

Try / catch

try { DcpDeveloperCertificateCache.EnsureDeveloperCertificateCache(manager, cert); }
catch (DcpDeveloperCertificateUnavailableException ex) when (ex.Message.Contains("user profile")) { Console.Error.WriteLine("Set HOME/USERPROFILE to a writable directory and retry."); }

Prevention

When it happens

Trigger: EnsureDeveloperCertificateCache runs in an environment where the user profile directory is missing - HOME or USERPROFILE environment variables unset (common in stripped-down service accounts, containers, cron jobs, or SSH sessions with sanitized environments) so the cache directory path is not fully qualified.

Common situations: Running `aspire doctor` inside a minimal Docker container without HOME set, systemd service or CI runner accounts with no home directory, sudo/su dropping environment variables, or Windows profiles failing to load for temp accounts.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Cli/Utils/EnvironmentChecker/DcpDeveloperCertificateCache.cs:24

using Aspire.Cli.Resources;
using Aspire.Hosting.Utils;
using Microsoft.AspNetCore.Certificates.Generation;

namespace Aspire.Cli.Utils.EnvironmentChecker;

internal static class DcpDeveloperCertificateCache
{
    public static string EnsureDeveloperCertificateCache(CertificateManager certificateManager, X509Certificate2 certificate)
    {
        if (!certificate.IsAspNetCoreDevelopmentCertificate() || string.IsNullOrWhiteSpace(certificate.Thumbprint))
        {
            throw new DcpDeveloperCertificateUnavailableException(DoctorCommandStrings.DcpDeveloperCertificateInvalidForCacheDetails);
        }

        var cacheDirectory = CertificateHelpers.AspireDevCertsHttpsCacheDirectory;
        if (!Path.IsPathFullyQualified(cacheDirectory))
        {
            throw new DcpDeveloperCertificateUnavailableException(DoctorCommandStrings.DcpDeveloperCertificateUserProfileMissingDetails);
        }

        var lookup = CertificateHelpers.GetAspireCertificateHash(certificate);
        var certificatePath = Path.Combine(cacheDirectory, $"{lookup}.crt");
        var keyPath = Path.ChangeExtension(certificatePath, ".key");

        // The public certificate export does not require private key access, so older caches with
        // a key but no certificate can be filled without re-exporting the cached key.
        certificateManager.ExportCertificate(certificate, certificatePath, includePrivateKey: !File.Exists(keyPath), password: null, CertificateKeyExportFormat.Pem);

        return certificatePath;
    }
}

View on GitHub (pinned to 25830f84bd)