Bar

NuGet ServerにnupkgをプッシュするとHTTP 500 Errorが発生する場合の対処法

ここ数日、Windows Server 2012 R2 EssentialsのIISにNuGet Serverを立ててPackagemanagement(a.k.a OneGet)を遊んでいます。
あるアプリケーションのnupkgファイルをNuGet Serverへプッシュしたところ、HTTP 500 Error(Internal Server Error)が発生する問題に遭遇。
今回は、NuGet ServerにnupkgをプッシュするとHTTP 500 Errorが発生する場合の対処法をメモ。

構成

  • Windows Server 2012 R2 Essentials with Update
  • IIS 8.5(9600.16384)
    • サイト名:OnegetRepo
    • 認証方法:匿名認証
  • NuGet Server 2.8.6
  • NuGet Command Line v3.3.0

問題

クライアントPCからnupkgファイルをnuget pushするとHTTP 500 Error(Internal Server Error)が発生しました。
PS C:\PowerShell\nuspec> .\nuget.exe push c:\powershell\nuspec\hoge.nupkg -s http://192.168.xxx.xxx:8080/ {GUID}
hoge を 'http://192.168.xxx.xxx:8080/' にプッシュしています...
.\nuget.exe : Failed to process request. 'Internal Server Error'. 
発生場所 行:1 文字:1
+ .\nuget.exe push c:\powershell\nuspec\hoge.nupkg -s  ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Failed to proce...Server Error'. :String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
リモート サーバーがエラーを返しました: (500) 内部サーバー エラーです.

NuGet Server上でも同じInternal Server Error(500)が発生しました。
PS C:\PowerShell\nuspec> .\nuget.exe push .\hoge.nupkg -s http://192.168.xxx.xxx:8080/ {GUID}
hoge を 'http://192.168.xxx.xxx:8080/' にプッシュしています...
Failed to process request. 'Internal Server Error'.
リモート サーバーがエラーを返しました: (500) 内部サーバー エラーです.

原因

IISのエラー ログを確認します。
※Webサイトの保存先はIISの設定画面から確認してください。
※ファイル名の時刻はUTC(協定世界時)です
c:\iis\OnegetRepo\App_Data\error-yyyy-MM-ddhhmmssZ-{GUID}.xml

ログを確認すると、適切なアクセス権限がない事が分かりました。
<error application="/LM/W3SVC/4/ROOT" detail="System.UnauthorizedAccessException: パス 'D:\Packages\<Package Name>.nupkg' へのアクセスが拒否されました。
   場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   場所 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   場所 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   場所 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
   場所 NuGet.PhysicalFileSystem.AddFileCore(String path, Action`1 writeToStream)
   場所 NuGet.Server.Infrastructure.ServerPackageRepository.AddPackage(IPackage package)
   場所 NuGet.Server.PackageService.CreatePackage(HttpContextBase context)
   場所 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   場所 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)" errorid="{GUID}" host="<Host_Name>" message="パス 'D:\Packages\<Package Name>.nupkg' へのアクセスが拒否されました。" source="mscorlib" time="2016-01-20T13:52:36.1398142Z" type="System.UnauthorizedAccessException">

HTTP 500 エラーになる場合と正常にアップロードできた場合のアクセス権限を比較してみました。
アップロード済みのnupkgファイルにWebサイト名と同じユーザー グループ(OnegetRepo)が付与されていない為、HTTP 500 Errorが発生した次第です。

なぜこうなったか。
作業中に手動でパッケージ フォルダーにnupkgファイルをコピーしたためです。
そもそもやってはいけないオペレーションですね、反省・・・
nuget.exeからプッシュした場合

ファイルを手動でコピーした場合
手動でコピーした場合、OnegetRepo ユーザーグループがありません。

対処法

アクセス権限がないNuGet Server上のnupkgファイルを手動で削除します。
削除後にnuget pushを実行するとアップロードが成功しました。