本文へスキップ
ecdsa.com
.NET SslStream / HttpClient.NET

エラーメッセージ

Received an unexpected EOF or 0 bytes from the transport stream.

別の表記

  • System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.

HttpClient はこれを「The SSL connection could not be established, see inner exception.」でラップします。.NET Framework アプリケーションのログには、同じ状況が「Authentication failed because the remote party has closed the transport stream.」としてよく現れます。

.NET SslStream / HttpClient — IOException: the peer closed the connection during the TLS handshake

このエラーの意味

SslStream が TLS ハンドシェイクを行っている最中に、リモート側(または途中の機器)が TLS アラートを送らずに TCP 接続を閉じました。.NET には、ストリームが閉じられたこと以外に報告できる理由がありません。通常は、サーバーが何も通知せずにハンドシェイクを拒否したか、プロキシやファイアウォールが接続を切断したかのどちらかです。

発生する理由

修正方法

  1. 1.

    同じマシンからハンドシェイクをテストする

    openssl s_client でも切断される場合、問題はネットワークかサーバーにあります。成功する場合は、プロトコルバージョンと SNI を .NET クライアントと比較してください。

    bash
    # Does a plain TLS handshake from the same host work?
    openssl s_client -connect api.example.com:443 -servername api.example.com -brief </dev/null
    openssl s_client -connect api.example.com:443 -servername api.example.com -tls1_2 -brief </dev/null
  2. 2.

    必須のプロキシを使う

    ネットワークが直接接続を許可していない場合は、ハンドラーで(または Linux では HTTPS_PROXY で)プロキシを設定してください。

    csharp
    // Use the corporate proxy explicitly (HttpClient also honours HTTPS_PROXY / system settings)
    var handler = new SocketsHttpHandler { Proxy = new WebProxy("http://proxy.example.net:3128"), UseProxy = true };
    using var client = new HttpClient(handler);
  3. 3.

    .NET Framework:TLS 1.2 を有効にする

    4.7 以降をターゲットにして OS にプロトコルを選ばせるか、それができるまでの間は ServicePointManager.SecurityProtocol に TLS 1.2 を追加してください。

    csharp
    // .NET Framework 4.x apps compiled for old targets may still offer only TLS 1.0:
    // target 4.7+ (OS defaults) or, as a stop-gap, enable TLS 1.2 explicitly
    System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;

関連するエラー

署名エラーデータベースをすべて見る