IIS+.NET Frameworkの環境構築で出たエラーコード0x80070021の対処法

こんにちは。インフラエンジニアの木村奈美です。 今回は、IIS+.NET Frameworkの環境を構築していてハマった、エラーコード 0x80070021 の対処法について書きます。

結論

  • なぜかIISのモジュールとハンドラーがなくなっていた
  • IISの再インストールで解決

…と、解決方法は至ってシンプルなのですが、エラーコードで検索した際に別の解決策しかヒットしなかったため、長時間ハマってしまいました。

同じ問題にハマっている人の助けになればと思い、その一部始終をご紹介します。

環境

  • Windows Server 2019
  • IIS 10
  • .NET Framework 4.8

発生までの流れ

開発環境で動作確認ができたため、同じ手順で検証環境を構築していました。

構築手順

以下の手順で構築しました。 なお、コマンドはすべてPowerShellで実行します。

IISをインストール

> Install-WindowsFeature Web-Server -IncludeManagementTools

ASP.NETを有効化 (この手順を忘れていて、後から実行したのが問題と関係しているかも?)

> Install-WindowsFeature Web-Asp-Net45

ドキュメントルートのディレクトリを変更する

> Import-Module WebAdministration
> Set-ItemProperty "IIS:\Sites\Default Web Site\" -name physicalPath -value "C:\prjname\webapp"

# 確認
> Get-Website -Name "Default Web Site"

Name             ID   State      Physical Path                  Bindings
----             --   -----      -------------                  --------
Default Web Site 1    Started    C:\prjname\webapp              http *:80:

.NET Framework 4.8 をインストールする

  1. Windows 用の Microsoft .NET Framework 4.8 オフライン インストーラー にアクセスする
  2. 「Microsoft .NET Framework 4.8 オフライン インストーラー パッケージを今すぐダウンロードしてください。」をクリックする
  3. exeファイルをダウンロードして実行する
  4. ライセンス条項に同意して「インストール」ボタンを押す
  5. インストールが完了するとサーバーの再起動を促されるため、再起動する

そして、ビルド済みのアプリをドキュメントルートに設置し、いざ動作確認!

エラー発生

curl でlocalhostのURLを叩くと、以下のようなエラーが出ました。 ブラウザで見ても同様です。

> curl http://localhost/api/healthcheck
curl : HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration
data for the page is invalid.Detailed Error Information:
Module   IIS Web Core
Notification   BeginRequest
Handler   Not yet determined
Error Code   0x80070021
Config Error   この構成セクションをこのパスで使用できません。
この問題は、親レベルでセクションがロックされているときに発生します。
ロック状態は既定で設定されているか (overrideModeDefault="Deny")、
または overrideMode="Deny" もしくは従来の allowOverride="false" を
含んだ場所タグによって明示的に設定されます。
Config File   \\?\C:\prjname\webapp\web.config
Requested URL   http://localhost:80/api/healthcheck
Physical Path   C:\prjname\webapp\api\healthcheck
Logon Method   Not yet determined
Logon User   Not yet determined
 Config Source:
   18:     </security>
   19:     <handlers>
   20:       <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
 More Information:
This error occurs when there is a problem reading the configuration file
for the Web server or Web application. In some cases, the event logs may
contain more information about what caused this error.
View more information »
発生場所 行:1 文字:1
+ curl http://localhost/api/healthcheck
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest]、WebExce
    ption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

調査

エラーコード 0x80070021 で検索してみると、ヒットしたのは以下の2パターンでした。

  • ASP.NET、ISAPIフィルター、ISAPI拡張がインストールされていない
  • C:\Windows\System32\inetsrv\config\applicationHost.config の編集が必要

前者はすでにインストール済み。 コマンドでインストールしたので、念のためサーバーマネージャーからも確認しましたが、ちゃんとあります。

f:id:nami_ki:20211203172429p:plain
インストール済みであることを確認

後者はネット上の記事を参考にいろいろ試してみましたが、解決しませんでした。

試した例

<section name=”modules” allowDefinition=”MachineToApplication” overrideModeDefault=”Deny” />
↓
<section name=”modules” allowDefinition=”MachineToApplication” overrideModeDefault=”Allow” />
<section name="handlers" overrideModeDefault="Deny" />
↓
<section name="handlers" overrideModeDefault="Allow" />

モジュールとハンドラーがない!?

発見

チームメンバーと協力して調査していた際に、「IISのモジュールに URLMappingModule はありますか?」と訊かれました。 そこで、 IISマネージャー > サーバー名 > モジュール を開いてモジュール一覧を確認しました。

以下が正常なサーバーのモジュールです。

f:id:nami_ki:20211203172528p:plain
正常なサーバーのモジュール。マネージドモジュールがある

問題のサーバーのモジュールを確認すると…

f:id:nami_ki:20211203172601p:plain
問題のサーバーのモジュール。マネージドモジュールがない

正常なサーバーと比べて、マネージドモジュールが全くありません。

ついでにハンドラーを見てみると…

以下が正常なサーバーのハンドラー。

f:id:nami_ki:20211203172654p:plain
正常なサーバーのハンドラー。1画面に収まらないぐらいある

そして、以下が問題のサーバーのハンドラー。

f:id:nami_ki:20211203172724p:plain
問題のサーバーのハンドラー。明らかに少ない

こちらも明らかに少ないです。

モジュールとハンドラーの追加が必要…?

最初は モジュールの追加方法 を参考に、ちまちま1つずつモジュールを入れていました。

しかし、これではあまりに手間がかかりすぎます。 そもそも、開発環境ではこんなことしなくても動いたのに、何かもっと根本的なところがおかしいんじゃないか…という疑念が浮かびました。

問題のサーバーは、2台あるサーバーのうち1台目だったので、試しに2台目で同様の構築手順を試してみました。 すると、 モジュールもハンドラーも揃っており、難なく動きました。 1台目と2台目は同条件のAzure VMなので、マシンの差異はないはずです。

IIS再インストール

さすがにおかしいと思い、別の方向から解決を試みました。 IISの再インストールです。

サーバーマネージャー > 管理 > 役割と機能の削除 > 「Webサーバー(IIS)」のチェックを外す > 削除 でアンインストールしたあと、冒頭の構築手順を使って再度インストールしました。

さて、モジュールとハンドラーはあるのか…

f:id:nami_ki:20211203172817p:plain
問題のサーバーのモジュール。マネージドモジュールが増えている

f:id:nami_ki:20211203172840p:plain
問題のサーバーのハンドラー。有効ハンドラーが増えている

あった!!!!!!

アプリも無事に動いて、胸をなでおろしました。

まとめ

結局、モジュールとハンドラーがなくなっていた理由は不明です。心当たりといえば、ASP.NETの有効化を忘れていて後の方に対応したことぐらいですが、関係あるのかな…。

なにはともあれ、解決できてよかったです。

解決に至った重要なポイントは以下の3つだと思います。

  • モジュールとハンドラーがないことに気付いた
  • 同条件のサーバーではモジュールとハンドラーがあり、問題なく動くことを確認できた
  • モジュールを1つ1つ入れていくのはおかしいと疑って、再インストールという別の手段をとった

この記事が誰かの助けになれば幸いです。