指定--ignore-failed-sources后dotnet-ef安装失败的原因与解决方案
问题
在Azure DevOps Pipelines构建.NET 6项目时,执行安装Entity Framework工具的步骤时,尽管已指定--ignore-failed-sources参数,且公共nuget.org源已找到对应包,但仍因401 Unauthorized异常失败。尝试添加--version 6.*适配.NET 6也未解决问题,请问异常原因及解决方法?
错误日志
"C:\Program Files\dotnet\dotnet.exe" tool update --verbosity diagnostic --global --disable-parallel --version 6.* --ignore-failed-sources dotnet-ef [NuGet Manager] [Info] GET https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/index.json [NuGet Manager] [Info] GET https://pkgs.dev.azure.com/<private>/_packaging/<private>/nuget/v3/registrations2-semver2/dotnet-ef/index.json [NuGet Manager] [Info] GET https://nuget.<private>.com/v3/registration/dotnet-ef/index.json [NuGet Manager] [Info] OK https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/index.json 70ms [NuGet Manager] [Info] GET https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/0.0.1-alpha/3.1.28.json [NuGet Manager] [Info] OK https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/0.0.1-alpha/3.1.28.json 32ms [NuGet Manager] [Info] Unauthorized https://pkgs.dev.azure.com/<private>/_packaging/<private>/nuget/v3/registrations2-semver2/dotnet-ef/index.json 149ms [NuGet Manager] [Info] Unauthorized https://nuget.<private>.com/v3/registration/dotnet-ef/index.json 164ms [NuGet Manager] [Info] GET https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/3.1.29/6.0.23.json [NuGet Manager] [Info] OK https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/3.1.29/6.0.23.json 37ms [NuGet Manager] [Info] GET https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/6.0.24/9.0.0-preview.6.24327.4.json [NuGet Manager] [Info] OK https://api.nuget.org/v3/registration5-gz-semver2/dotnet-ef/page/6.0.24/9.0.0-preview.6.24327.4.json 36ms Unhandled exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at NuGet.Protocol.HttpSource.<>c__DisplayClass15_0`1.<GetAsync>b__0.MoveNext() --- End of stack trace from previous location --- at NuGet.Common.ConcurrencyUtilities.ExecuteWithFileLockedAsync[T](String filePath, Func`2 action, CancellationToken token) at NuGet.Common.ConcurrencyUtilities.ExecuteWithFileLockedAsync[T](String filePath, Func`2 action, CancellationToken token) at NuGet.Protocol.HttpSource.GetAsync[T](HttpSourceCachedRequest request, Func`2 processAsync, ILogger log, CancellationToken token) at NuGet.Protocol.PackageMetadataResourceV3.LoadRegistrationIndexAsync(HttpSource httpSource, Uri registrationUri, String packageId, SourceCacheContext cacheContext, Func`2 processAsync, ILogger log, CancellationToken token) at NuGet.Protocol.PackageMetadataResourceV3.GetMetadataAsync(String packageId, Boolean includePrerelease, Boolean includeUnlisted, VersionRange range, SourceCacheContext sourceCacheContext, ILogger log, CancellationToken token) at NuGet.Protocol.PackageMetadataResourceV3.GetMetadataAsync(String packageId, Boolean includePrerelease, Boolean includeUnlisted, SourceCacheContext sourceCacheContext, ILogger log, CancellationToken token) at Microsoft.DotNet.Cli.NuGetPackageDownloader.NuGetPackageDownloader.GetPackageMetadataAsync(PackageSource source, String packageIdentifier, Boolean includePrerelease, Boolean includeUnlisted, CancellationToken cancellationToken) at Microsoft.DotNet.Cli.NuGetPackageDownloader.NuGetPackageDownloader.GetMatchingVersionInternalAsync(String packageIdentifier, IEnumerable`1 packageSources, VersionRange versionRange, CancellationToken cancellationToken) at Microsoft.DotNet.Cli.NuGetPackageDownloader.NuGetPackageDownloader.GetBestPackageVersionAsync(PackageId packageId, VersionRange versionRange, PackageSourceLocation packageSourceLocation) at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.<>c__DisplayClass8_0.<InstallPackage>b__0() at Microsoft.DotNet.Cli.TransactionalAction.Run[T](Func`1 action, Action commit, Action rollback) at Microsoft.DotNet.Tools.Tool.Install.ToolInstallGlobalOrToolPathCommand.<>c__DisplayClass20_0.<Execute>b__1() at Microsoft.DotNet.Tools.Tool.Install.ToolInstallGlobalOrToolPathCommand.RunWithHandlingInstallError(Action installAction) at Microsoft.DotNet.Tools.Tool.Install.ToolInstallGlobalOrToolPathCommand.Execute() at Microsoft.DotNet.Tools.Tool.Update.ToolUpdateGlobalOrToolPathCommand.Execute() at System.CommandLine.Invocation.InvocationPipeline.Invoke(ParseResult parseResult) at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient) ##[error]Error: The process 'C:\Program Files\dotnet\dotnet.exe' failed with exit code 1 Info: Azure Pipelines hosted agents have been updated and now contain .Net 5.x SDK/Runtime along with the older .Net Core version which are currently lts. Unless you have locked down a SDK version for your project(s), 5.x SDK might be picked up which might have breaking behavior as compared to previous versions. You can learn more about the breaking changes here: https://docs.microsoft.com/en-us/dotnet/core/tools/ and https://docs.microsoft.com/en-us/dotnet/core/compatibility/ . To learn about more such changes and troubleshoot, refer here: https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/build/dotnet-core-cli?view=azure-devops#troubleshooting ##[error]Dotnet command failed with non-zero exit code on the following projects : [ '' ] Finishing: Install dotnet-ef
YAML配置片段
variables: - name: BuildParameters.RestoreBuildProjects value: '**/*.csproj' - name: BuildParameters.TestProjects value: '**/*[Tt]ests/*.csproj' - name: BuildConfiguration value: 'release' trigger: branches: include: - refs/heads/master name: $(date:yyyyMMdd)$(rev:.r) jobs: - job: Job_1 displayName: Agent job 1 pool: vmImage: windows-2022 steps: - checkout: self - task: DotNetCoreCLI@2 displayName: Restore inputs: command: 'restore' projects: '$(BuildParameters.RestoreBuildProjects)' feedsToUse: 'config' nugetConfigPath: 'nuget.config' externalFeedCredentials: 'Telerik NuGet source' - task: DotNetCoreCLI@2 displayName: Build inputs: projects: $(BuildParameters.RestoreBuildProjects) arguments: --configuration $(BuildConfiguration) - task: DotNetCoreCLI@2 displayName: Test enabled: False inputs: command: test projects: $(BuildParameters.TestProjects) arguments: --configuration $(BuildConfiguration) - task: DotNetCoreCLI@2 displayName: Publish inputs: command: publish publishWebProjects: True projects: $(BuildParameters.RestoreBuildProjects) arguments: --configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory) zipAfterPublish: True - task: PublishBuildArtifacts@1 displayName: 'Publish Artifact: drop' condition: succeededOrFailed() inputs: TargetPath: '\\my\share\$(Build.DefinitionName)\$(Build.BuildNumber)' - task: DotNetCoreCLI@2 displayName: Install dotnet-ef inputs: command: 'custom' custom: 'tool' arguments: 'update --verbosity diagnostic --global --disable-parallel --version 6.* --ignore-failed-sources dotnet-ef'
代理与任务信息
Starting: Initialize job Agent name: 'Hosted Agent' Agent machine name: 'fv-az510-690' Current agent version: '3.241.0' Operating System Microsoft Windows Server 2022 10.0.20348 Datacenter Runner Image Image: windows-2022 Version: 20240723.1.0 Included Software: https://github.com/actions/runner-images/blob/win22/20240723.1/images/windows/Windows2022-Readme.md Image Release: https://github.com/actions/runner-images/releases/tag/win22%2F20240723.1 Runner Image Provisioner 2.0.373.1 Current image version: '20240723.1.0' Agent running as: 'VssAdministrator'
Starting: Install dotnet-ef ============================================================================== Task : .NET Core Description : Build, test, package, or publish a dotnet application, or run a custom dotnet command Version : 2.242.0 Author : Microsoft Corporation Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/build/dotnet-core-cli ============================================================================== C:\Windows\system32\chcp.com 65001 Active code page: 65001
原因分析
--ignore-failed-sources参数的实际作用范围:该参数仅忽略无法找到目标包的源,但对于返回401未授权这类身份验证错误的源,NuGet会将其视为严重异常,不会进行忽略,导致整个命令失败。- NuGet配置的继承:Restore步骤中指定了包含私有源的
nuget.config,dotnet tool update命令会继承这个配置中的所有源,但这些私有源没有配置有效的访问凭据,访问时触发401错误。
解决方案
方案1:强制指定仅使用nuget.org源安装
修改Install dotnet-ef步骤的arguments,添加--source参数指定仅使用公共nuget源,避免访问私有源:
- task: DotNetCoreCLI@2 displayName: Install dotnet-ef inputs: command: 'custom' custom: 'tool' arguments: 'update --verbosity diagnostic --global --disable-parallel --version 6.* --ignore-failed-sources --source https://api.nuget.org/v3/index.json dotnet-ef'
方案2:使用临时NuGet配置文件
在安装dotnet-ef前,创建一个仅包含nuget.org的临时配置文件,让命令使用该配置:
- script: | echo '<?xml version="1.0" encoding="utf-8"?><configuration><packageSources><add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" /></packageSources></configuration>' > temp_nuget.config displayName: 创建临时NuGet配置 - task: DotNetCoreCLI@2 displayName: Install dotnet-ef inputs: command: 'custom' custom: 'tool' arguments: 'update --verbosity diagnostic --global --disable-parallel --version 6.* --ignore-failed-sources --configfile temp_nuget.config dotnet-ef' - script: del temp_nuget.config displayName: 清理临时配置文件
方案3:为私有源配置有效凭据
如果需要保留私有源配置,需确保访问私有源的凭据正确:
- 对于Azure Artifacts私有源,在Install dotnet-ef步骤前添加
NuGetAuthenticate@1任务,自动注入访问凭据 - 对于其他私有源,在
nuget.config中配置正确的凭据,或通过Pipeline变量存储凭据并动态替换到配置中
内容的提问来源于stack exchange,提问作者alik
相关产品推荐
相关产品推荐

