microsoft/aspire · error · ProjectUpdaterException
Failed to discover NuGet.config files.
Error message
Failed to discover NuGet.config files.
What it means
During ProjectUpdater.UpdateProjectAsync, for explicit (version-pinned) channels the updater asks the dotnet runner for the list of NuGet.config paths applicable to the project directory. If the command exits non-zero, returns null, or returns an empty list, it throws ProjectUpdaterException(FailedDiscoverNuGetConfig) because update feasibility cannot be evaluated without knowing the feed configuration.
Solutions
- Run dotnet restore in the project directory to surface the underlying NuGet config error and fix the reported NuGet.config line.
- Validate the NuGet.config XML syntax and <packageSources> entries.
- Ensure a working dotnet SDK is on PATH and global NuGet config (~/.nuget/NuGet/NuGet.Config) is intact.
- Temporarily move suspect NuGet.config files out of the directory tree and retry to isolate the broken one.
Example fix
// before (broken config) <packageSources><add key="nuget" value="https//api.nuget.org/v3/index.json" /></packageSources> // after (fixed URL) <packageSources><add key="nuget" value="https://api.nuget.org/v3/index.json" /></packageSources>
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check: ensure a parseable NuGet.config exists in the tree
var configs = Directory.EnumerateFiles(projectDir, "NuGet.config", SearchOption.AllDirectories);
foreach (var c in configs)
System.Xml.Linq.XDocument.Load(c); // throws on malformed XML before calling the updater Try / catch
try
{
await updater.UpdateProjectAsync(context, cancellationToken);
}
catch (ProjectUpdaterException ex) when (ex.Message.Contains("NuGet.config"))
{
Console.Error.WriteLine($"NuGet config discovery failed: {ex.Message}. Run 'dotnet restore' to see the underlying config error.");
} Prevention
- Validate NuGet.config files (XML syntax, packageSources URLs) after editing them.
- Keep a working dotnet SDK on PATH in CI images.
- Avoid checked-in NuGet.config files with stale or unreachable feed URLs.
When it happens
Trigger: UpdateProjectAsync with a PackageChannelType.Explicit channel where runner.GetNuGetConfigPathsAsync returns a non-zero exit code, null, or an empty path array — e.g. dotnet nuget locals/config evaluation failing in the project directory.
Common situations: Corrupted or malformed NuGet.config XML in the project tree; NuGet.config with invalid schema; a directory with no NuGet.config and global config broken; restricted environments where the dotnet CLI cannot read config; PATH pointing at a broken dotnet SDK.
Understand the failure class
Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.
Related errors
- Failed to restore packages for project
- No package found with ID
- aspire-managed not found in layout.
- Bundle layout not found. Cannot perform NuGet restore in…
- Bundle layout not found. Cannot perform NuGet search in…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/9a76d4c4691d94f8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Cli/Projects/ProjectUpdater.cs:98
// Display warning if fallback parsing was used
if (fallbackUsed)
{
interactionService.DisplayMessage(KnownEmojis.Warning, $"[yellow]{UpdateCommandStrings.FallbackParsingWarning}[/]", allowMarkup: true);
interactionService.DisplayEmptyLine();
}
if (!await interactionService.PromptConfirmAsync(UpdateCommandStrings.PerformUpdatesPrompt, context.ConfirmBinding, cancellationToken: cancellationToken))
{
return new ProjectUpdateResult { UpdatedApplied = false };
}
if (channel.Type == PackageChannelType.Explicit)
{
var (configPathsExitCode, configPaths) = await runner.GetNuGetConfigPathsAsync(projectFile.Directory!, new(), cancellationToken);
if (configPathsExitCode != 0 || configPaths is null || configPaths.Length == 0)
{
throw new ProjectUpdaterException(UpdateCommandStrings.FailedDiscoverNuGetConfig);
}
var configPathDirectories = configPaths.Select(Path.GetDirectoryName).ToArray();
var fallbackNuGetConfigDirectory = executionContext.WorkingDirectory.FullName;
// If there is one or zero config paths we assume that we should use
// the fallback (there should always be one, but just for exhaustivenss).
// If there is more than one we just make sure that the first on in the list
// isn't a global config (on Windows with .NET and VS installed you'll have 3
// global config files but the first one should be the NuGet in AppData).
// The final rule should never ever be invoked, its just to get around CS8846
// which does not evaluate when statements for exhaustiveness.
var recommendedNuGetConfigFileDirectory = configPathDirectories switch
{
{ Length: 0 or 1 } => fallbackNuGetConfigDirectory,
var p when p.Length > 1 => IsGlobalNuGetConfig(p[0]!) ? fallbackNuGetConfigDirectory : p[0],
// CS8846 error if we don't put this rule here even though we do "when"View on GitHub (pinned to 25830f84bd)