「There was no endpoint listening at [URL] that could accept the message」 というエラーは、WCF で最も頻繁に発生する例外の一つであり、同時に最も原因が特定しにくいエラーでもあります。URL が間違っているように見えますが、実際の原因はアプリケーションプールの停止、Windows ファイアウォールの設定、HTTP.sys の URL 予約など多岐にわたります。
この記事では、考えられるすべての原因と、体系的な診断ワークフローを解説します。
エラーの全文
例外の典型的な内容は以下のとおりです。
System.ServiceModel.EndpointNotFoundException:
There was no endpoint listening at http://server:8080/MyService.svc
that could accept the message. This is often caused by an incorrect address
or SOAP action. See InnerException, if present, for more details.
Inner Exception:
System.Net.WebException: The remote server returned an error: (404) Not Found.
内部例外 (InnerException) が真の手がかりです。外側の EndpointNotFoundException は汎用的なメッセージですが、内部の WebException には HTTP ステータスコードが含まれています。
| 内部例外 | 考えられる原因 |
|---|---|
(404) Not Found | URL パスが間違っている、またはサービスが未デプロイ |
(403) Forbidden | 認証・認可の問題 |
(503) Service Unavailable | アプリケーションプールの停止またはリサイクル中 |
Unable to connect to the remote server | ネットワーク / ファイアウォールの問題、またはサーバープロセス未起動 |
原因 1: URL の不一致
最も基本的な原因です。クライアント側のエンドポイント設定が、サービスの実際のアドレスと一致していません。
<!-- クライアント設定 -->
<endpoint address="http://server:8080/MyService.svc"
binding="basicHttpBinding"
contract="IMyService" />
よくある URL の間違い:
- ポート番号の誤り。 IIS のデフォルトポートは 80 ですが、セルフホストのサービスではカスタムポートがよく使われます。
.svc拡張子の欠落。 IIS でホストされた WCF サービスは URL に.svc拡張子が必要です。- HTTP と HTTPS の不一致。 サーバーが HTTPS のみで構成されている場合、HTTP リクエストは失敗します。
- 末尾スラッシュの差異。 WCF の一部の設定は末尾スラッシュの有無で動作が変わります。
簡易確認方法 — サービスの URL をブラウザまたは curl で開いてみます。
curl -v http://server:8080/MyService.svc
WSDL ページまたは WCF メタデータページが表示されれば URL は正しく、問題は別の箇所にあります。404 が返る場合は URL またはデプロイに問題があります。
原因 2: サービスが起動していない / デプロイされていない
IIS でホストされている場合の確認手順です。
-
.svcファイルが期待するパスに存在するか確認する。 IIS サイトの物理ディレクトリ直下を確認してください。 -
IIS マネージャーでアプリケーションが作成されているか確認する。 フォルダにファイルがあるだけでは不十分で、IIS にアプリケーション (仮想ディレクトリではなく) が作成されている必要があります。
-
アプリケーションプールが実行中か確認する。
# アプリケーションプールのステータスを確認
Get-WebAppPoolState -Name "MyAppPool"
# 停止している場合は再起動
Start-WebAppPool -Name "MyAppPool"
- イベントビューアー (Windows ログ > アプリケーション) で、アプリケーションプール起動時のエラーを確認してください。依存ライブラリの不足や config の不備によりプールが起動時にクラッシュし、繰り返し失敗の後 IIS が自動的にプールを無効化するケースがあります。
セルフホスト (Windows サービスまたはコンソールアプリ) の場合:
# サービスプロセスが起動しているか確認
Get-Process -Name "MyServiceHost" -ErrorAction SilentlyContinue
# Windows サービスのステータスを確認
Get-Service -Name "MyWcfService"
原因 3: ファイアウォールまたはネットワーク設定
サーバー上ではサービス URL にアクセスできるが、クライアントマシンからはアクセスできない場合、ネットワークレベルの問題です。
Windows ファイアウォール:
# ポートが開いているか確認
Test-NetConnection -ComputerName server -Port 8080
# 必要に応じてファイアウォールルールを追加
New-NetFirewallRule -DisplayName "WCF Service Port 8080" `
-Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow
ネットワークレベルの確認:
# クライアントマシンから
telnet server 8080
Test-NetConnection で TcpTestSucceeded: False と表示される場合、クライアントとサーバー間のファイアウォール、ロードバランサー、ネットワークセグメンテーションがトラフィックをブロックしています。
原因 4: HTTP.sys URL 予約 (セルフホストの場合)
IIS を使用しないセルフホストの WCF サービスでは、特定のポートでリッスンするために HTTP.sys の URL 予約が必要です。予約がない場合、サービス起動時に AddressAccessDeniedException がスローされ、リッスン状態になりません。
# 既存の予約を確認
netsh http show urlacl
# 予約を追加
netsh http add urlacl url=http://+:8080/MyService/ user="NT AUTHORITY\NETWORK SERVICE"
サービスを特定のアカウントで実行している場合は、user パラメータを適切に変更してください。予約追加後はサービスの再起動が必要です。
原因 5: サーバー側のバインディングまたはエンドポイント設定の不一致
サーバーは起動しているが、WCF のエンドポイント設定が期待するアドレスを公開していない場合があります。
<system.serviceModel>
<services>
<service name="MyNamespace.MyService">
<!-- クライアントはこのアドレスを使用する必要がある -->
<endpoint address=""
binding="basicHttpBinding"
contract="MyNamespace.IMyService" />
<!-- 相対アドレスはサブパスを作成する -->
<endpoint address="secure"
binding="wsHttpBinding"
contract="MyNamespace.IMyService" />
</service>
</services>
</system.serviceModel>
endpoint 要素の address 属性に注目してください。空文字列はベースアドレスにエンドポイントが存在することを意味します。"secure" のような値は http://server:8080/MyService.svc/secure にエンドポイントが存在することを意味します。
原因 6: IIS アプリケーションプールの ID と権限
アプリケーションプールが実行中でも、サービスの初期化時に必要なリソースへのアクセス権限がない場合があります。
# アプリケーションプールの ID を確認
Get-ItemProperty "IIS:\AppPools\MyAppPool" -Name processModel.identityType
# サービスディレクトリへの読み取りアクセスを付与
icacls "C:\inetpub\MyService" /grant "IIS AppPool\MyAppPool:(OI)(CI)R"
権限エラーによりアプリケーションプールがサイレントにクラッシュすると、クライアントには単に EndpointNotFoundException が表示されるだけで、明確な原因表示がありません。
体系的な診断ワークフロー
このエラーに遭遇した場合、以下の順序で確認してください。
Step 1: URL への到達性を確認する
# クライアントマシンから
curl -v http://server:8080/MyService.svc
有効なレスポンスが返る場合は Step 4 へ進みます。
Step 2: ネットワーク接続性を確認する
curl -v telnet://server:8080
接続が拒否された場合は、ファイアウォールの確認とサービスプロセスのリッスン状態を確認してください。
Step 3: サーバー上でサービスが起動しているか確認する
# 期待するポートでリッスンしているプロセスを確認
netstat -ano | findstr ":8080"
何もリッスンしていない場合はサービスが起動していません。イベントビューアー、サービスログ、アプリケーションプールのステータスを確認してください。
Step 4: クライアントとサーバーのエンドポイント設定を比較する
両方の config ファイルを並べて以下を確認します。
- アドレスが完全に一致している (スキーム、ホスト、ポート、パス)
- バインディングの種類が一致している
- コントラクトの名前空間と名前が一致している
Step 5: サーバー側で WCF トレースを有効にする
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing">
<listeners>
<add name="traceListener"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\logs\wcf-trace.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
生成された .svclog ファイルを Service Trace Viewer (SvcTraceViewer.exe) で開き、サーバーがリクエストを受信したかどうかを確認してください。
内部例外が (404) ではない場合
内部例外が (503) Service Unavailable を示している場合、サーバープロセスは存在するが一時的にリクエストを処理できない状態です。
- アプリケーションプールのリサイクル中。 IIS はデフォルトで 1740 分 (29 時間) ごとにアプリケーションプールをリサイクルします。リサイクル中はリクエストが一時的に失敗します。
- アプリケーションプールが無効化されている。 繰り返しの障害後に自動無効化されている可能性があります。
- 接続制限に達している。 WCF のデフォルトスロットルは同時セッション数 16、同時呼び出し数 16、同時インスタンス数 16 です。
スロットルの引き上げが必要な場合:
<serviceBehaviors>
<behavior name="ThrottledBehavior">
<serviceThrottling maxConcurrentCalls="64"
maxConcurrentSessions="200"
maxConcurrentInstances="200" />
</behavior>
</serviceBehaviors>
SOAPless による解決
EndpointNotFoundException の原因調査には、サーバーの構成ファイル、IIS マネージャー、ファイアウォール設定、HTTP.sys の情報へのアクセスが必要です。サードパーティの SOAP サービスを利用している場合、これらの情報にアクセスできないことがほとんどで、URL が正しいかサービスが起動しているかを推測するしかありません。
SOAPless はこの不確実性を解消します。ダッシュボードに WSDL URL を貼り付けるだけで、エンドポイントの検証が行われ、REST JSON エンドポイントが自動生成されます。ダッシュボード上のテストパネルで接続性を即座に確認でき、上流サービスの URL 変更やダウンタイムも .NET 例外ではなくわかりやすい診断情報として表示されます。
認証情報は AES-256-GCM で暗号化管理され、REST エンドポイントの OpenAPI 仕様も自動生成されます。WCF の config ファイルやバインディング設定のデバッグから解放され、動作する JSON API をすぐに利用できます。