microsoft/aspire · critical · ProjectUpdaterException

Failed to restore packages for project

Error message

Failed to restore packages for project {projectFile.FullName} after update.

What it means

After applying package updates to the project file, ProjectUpdater runs dotnet restore to bring the project back to a consistent state. If the restore command exits non-zero it throws ProjectUpdaterException with FailedToRestoreAfterUpdateFormat including the project path. The update itself was written, but the project no longer restores cleanly.

Solutions

  1. Run dotnet restore on the project manually and read the NU1xxx error to see the exact failing package or source.
  2. Check the targeted feed is reachable and credentials are valid (nuget.org or your mirror).
  3. If the update picked an incompatible version, revert or pin that package version in the project/Directory.Packages.props and retry the update.
  4. Clear the NuGet cache for the failing package (dotnet nuget locals http-cache --clear) and retry in case of corrupted cache entries.

Example fix

// before
<PackageVersion Include="Aspire.Hosting.Redis" Version="13.0.99" />  // never published
// after
<PackageVersion Include="Aspire.Hosting.Redis" Version="13.0.2" />
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check: verify key packages exist at the target versions before updating
foreach (var pkg in packageIds)
    await dotnet.RunAsync($"package search {pkg} --exact-match");

Try / catch

try
{
    await updater.UpdateProjectAsync(context, cancellationToken);
}
catch (ProjectUpdaterException ex) when (ex.Message.Contains("restore"))
{
    // Revert the project file from backup, then retry after fixing feed/versions
    File.Copy(projectFile.FullName + ".bak", projectFile.FullName, overwrite: true);
    Console.Error.WriteLine($"Post-update restore failed: {ex.Message}");
}

Prevention

When it happens

Trigger: UpdateProjectAsync's post-update step where runner.RestoreAsync(projectFile, ...) returns a non-zero exit code — restore fails with the newly written package versions (conflicts, unreachable feed, broken transitive dependency).

Common situations: Updated package version does not exist on the configured feed (stale/offline mirror); version conflicts introduced by bumping central package versions; private feed credentials expired; network outage during restore; incompatible transitive dependency set after the update.

Related errors


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

Appendix: source

Thrown at src/Aspire.Cli/Projects/ProjectUpdater.cs:197

        // feed, but the rest are still on their previous (often stable) versions which may
        // not be carried by that feed. Mapping then blocks the fallback to nuget.org, producing
        // NU1103 for every not-yet-bumped Aspire reference. Deferring the restore until all
        // edits are applied means every Aspire* reference resolves against versions that
        // exist in the configured feed.
        // Restoring the AppHost project transitively restores referenced projects, so a single
        // restore here covers both traditional PackageReference and Directory.Packages.props
        // (CPM) update paths. The 'dotnet restore' command accepts both .csproj and file-based
        // (apphost.cs) program files as the positional argument.
        // See https://github.com/dotnet/aspire/issues/15891.
        await interactionService.ShowStatusAsync(
            UpdateCommandStrings.RestoringPackagesAfterUpdate,
            async () =>
            {
                var restoreExitCode = await runner.RestoreAsync(projectFile, new(), cancellationToken);

                if (restoreExitCode != 0)
                {
                    throw new ProjectUpdaterException(string.Format(CultureInfo.InvariantCulture, UpdateCommandStrings.FailedToRestoreAfterUpdateFormat, projectFile.FullName));
                }

                return 0;
            });

        interactionService.DisplayEmptyLine();

        interactionService.DisplaySuccess(UpdateCommandStrings.UpdateSuccessfulMessage);
        return new ProjectUpdateResult { UpdatedApplied = true };
    }

    private static bool IsGlobalNuGetConfig(string path)
    {
        if (Environment.OSVersion.Platform == PlatformID.Win32NT)
        {
            return path.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), StringComparison.Ordinal);
        }
        else

View on GitHub (pinned to 25830f84bd)