microsoft/aspire · error · NuGetPackageCacheException

Failed to retrieve template packages via cache.

Error message

Failed to retrieve template packages via cache.

What it means

NuGetPackageCache.GetTemplatePackagesAsync queries the Aspire.ProjectTemplates package via dotnet search and caches it in IMemoryCache. MemoryCache.GetOrCreateAsync can return null when the cached factory produces null; the code treats a null result as a cache failure and throws NuGetPackageCacheException 'Failed to retrieve template packages via cache.'

Solutions

  1. Check network access to nuget.org (or your configured feed) and ensure Aspire.ProjectTemplates is available there
  2. Inspect/fix nuget.config in the working directory or pass an explicit --nuget-config
  3. Retry the command (the result is cached; a transient search failure may clear on retry)
  4. Update the Aspire CLI; if it persists, run with debug logging and report the underlying search failure
Defensive patterns

Strategy: retry

Validate before calling

// Confirm the template package is visible on the configured source first
dotnet package search Aspire.ProjectTemplates --exact-match --prerelease

Try / catch

try
{
    var templates = await cache.GetTemplatePackagesAsync(workingDir, prerelease, nugetConfig, ct);
}
catch (NuGetPackageCacheException ex) when (ex.Message.Contains("Failed to retrieve template packages"))
{
    // check feed connectivity / nuget.config, then retry
}

Prevention

When it happens

Trigger: GetTemplatePackagesAsync (e.g. `aspire new` template listing) when GetOrCreateAsync returns null — effectively when the underlying GetPackagesAsync search produced a null/empty result for Aspire.ProjectTemplates that collapsed to null in the cache path.

Common situations: NuGet source unreachable or misconfigured so the ProjectTemplates package is not found; template package filtered out by the Id filter; transient NuGet failure during `aspire new`; restrictive nuget.config in the working directory hiding nuget.org.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Cli/NuGet/NuGetPackageCache.cs:84

            packageId.Equals("Aspire.Hosting.Integration.Analyzers", StringComparison.OrdinalIgnoreCase);
    }
}

internal sealed class NuGetPackageCache(IDotNetCliRunner cliRunner, IMemoryCache memoryCache, AspireCliTelemetry telemetry, IFeatures features) : INuGetPackageCache
{
    private const int SearchPageSize = 1000;

    public async Task<IEnumerable<NuGetPackage>> GetTemplatePackagesAsync(DirectoryInfo workingDirectory, bool prerelease, FileInfo? nugetConfigFile, CancellationToken cancellationToken)
    {
        var nuGetConfigHashSuffix = nugetConfigFile is not null ? await ComputeNuGetConfigHashSuffixAsync(nugetConfigFile, cancellationToken) : string.Empty;
        var key = $"TemplatePackages-{workingDirectory.FullName}-{prerelease}-{nuGetConfigHashSuffix}";

        var packages = await memoryCache.GetOrCreateAsync(key, async (entry) =>
        {
            var packages = await GetPackagesAsync(workingDirectory, "Aspire.ProjectTemplates", null, prerelease, nugetConfigFile, true, cancellationToken);
            return packages.Where(p => p.Id.Equals("Aspire.ProjectTemplates", StringComparison.OrdinalIgnoreCase));

        }) ?? throw new NuGetPackageCacheException(ErrorStrings.FailedToRetrieveCachedTemplatePackages);

        return packages;
    }

    public async Task<IEnumerable<NuGetPackage>> GetIntegrationPackagesAsync(DirectoryInfo workingDirectory, bool prerelease, FileInfo? nugetConfigFile, CancellationToken cancellationToken)
    {
        return await GetPackagesAsync(workingDirectory, "Aspire.Hosting", null, prerelease, nugetConfigFile, true, cancellationToken);
    }

    public async Task<IEnumerable<NuGetPackage>> GetCliPackagesAsync(DirectoryInfo workingDirectory, bool prerelease, FileInfo? nugetConfigFile, CancellationToken cancellationToken)
    {
        var nuGetConfigHashSuffix = nugetConfigFile is not null ? await ComputeNuGetConfigHashSuffixAsync(nugetConfigFile, cancellationToken) : string.Empty;
        var key = $"CliPackages-{workingDirectory.FullName}-{prerelease}-{nuGetConfigHashSuffix}";

        var packages = await memoryCache.GetOrCreateAsync(key, async (entry) =>
        {
            // Set cache expiration to 1 hour for CLI updates
            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);

View on GitHub (pinned to 25830f84bd)