502 Bad Gateway - 重複ヘッダー

Apigee Edge のドキュメントを表示しています。
Apigee X のドキュメントに移動します。
情報

症状

クライアント アプリケーションが、API 呼び出しに対するレスポンスとして、エラーコード protocol.http.DuplicateHeader 付きの HTTP ステータス コード 502 Bad Gateway を受け取ります。

エラー メッセージ

クライアント アプリケーションは、次のレスポンス コードを受け取ります。

HTTP/1.1 502 Bad Gateway

また、次のようなエラー メッセージが表示されることがあります。

{
   "fault":{
      "faultstring":"Duplicate Header \"Expires\"",
      "detail":{
         "errorcode":"protocol.http.DuplicateHeader"
      }
   }
}

考えられる原因

このエラーは、Apigee Edge で重複が許可されていない特定の HTTP ヘッダーが、バックエンド サーバーから Apigee Edge に送信された HTTP レスポンスの一部として同じ値または異なる値で複数回表示される場合に発生します。

RFC 7230、セクション 3.2.2: Field Order に従い、ヘッダー フィールドのフィールド値全体がカンマ区切りのリストとして定義されている場合(つまり、#(values)] またはヘッダー フィールドが既知の例外である場合。Apigee Edge は、重複が許可されていない特定の同じヘッダーが、ターゲット/バックエンド サーバーから送信された HTTP レスポンス で複数回送信されていることを検出すると、502 Bad Gateway とエラーコード protocol.http.DuplicateHeader で応答します。

このエラーの原因として、次のことが考えられます。

原因 説明 トラブルシューティングの実施対象
レスポンスに重複するヘッダーがある バックエンド サーバーからのレスポンスに重複するヘッダーが含まれています。 Edge Public Cloud と Private Cloud のユーザー

共通の診断手順

次のいずれかのツールまたは手法を使用して、このエラーを診断します。

API Monitoring

API Monitoring を使用してエラーを診断するには:

  1. 適切なロールを持つユーザーとして Apigee Edge UI にログインします。
  2. 問題の調査対象となる組織に切り替えます。

  3. [Analyze] > [API Monitoring] > [Investigate] ページに移動します。
  4. エラーが発生した特定の期間を選択します。
  5. [プロキシ] フィルタが [すべて] に設定されていることを確認します。
  6. 障害コード時間をプロットします。
  7. 以下のように、障害コード protocol.http.DuplicateHeader が含まれるセルを選択します。

    大きい画像を表示

  8. 以下のように、障害コード protocol.http.DuplicateHeader に関する情報が表示されます。

    大きい画像を表示

  9. 上記の例に示すように、[ステータス コード] が 502 であることを確認します。
  10. [ログを表示] をクリックし、失敗したリクエストの行を開きます。
  11. [ログ] ウィンドウで、次の詳細をメモします。

    • ステータス コード: 502
    • 障害の発生元: target
    • 障害コード: protocol.http.DuplicateHeader
  12. Fault Sourcetarget です。これは、バックエンド サーバーからのレスポンスに重複するヘッダーが含まれていることを示します。

Trace ツール

Trace ツールを使用してエラーを診断するには:

  1. トレース セッションと、次のいずれかを有効にします。
    1. 502 Bad Gateway エラーが発生するまで待つか、
    2. 問題を再現できる場合は、API 呼び出しを行って 502 Bad Gateway エラーを再現します。
  2. [Show all Flow Infos] が有効になっていることを確認します。

  3. 失敗したリクエストのいずれかを選択し、トレースを確認します。
  4. トレースのさまざまなフェーズを調べて、障害が発生した場所を特定します。
  5. 通常、エラーは次の図に示すように、[Request sent to target server] フェーズの後のフローに表示されます。

    大きい画像を表示

  6. トレースからエラーの値をメモします。

    上記のトレース例では、エラーは Duplicate Header "Expires" として示されています。このエラーは、リクエストがバックエンド サーバーに送信された後に Apigee によって発生するため、バックエンド サーバーがヘッダー Expires を複数回送信したことを示します。

  7. トレースの AX(Analytics Data Recorded)フェーズに移動してクリックします。
  8. [Phase Details - Response Headers] セクションまでスクロールし、次に示すように X-Apigee-fault-codeX-Apigee-fault-source の値を特定します。

    大きい画像を表示

  9. X-Apigee-fault-codeX-Apigee-fault-source の値が protocol.http.DuplicateHeadertarget になります。これは、バックエンド サーバーがレスポンス ヘッダー Expires に重複するヘッダーを渡したことが原因でこのエラーが発生したことを示しています。
    レスポンス ヘッダー
    X-Apigee-fault-code protocol.http.DuplicateHeader
    X-Apigee-fault-source target
  10. プロキシ チェーンを使用しているかどうかを確認します。つまり、ターゲット サーバーまたはターゲット エンドポイントが Apigee で別のプロキシを呼び出しているかどうかを確認します。

    1. これを判断するには、[Request sent to target] サーバー フェーズに戻ります。[Curl を表示] をクリックします。

    2. [Curl for Request Sent to Target Server] ウィンドウが開き、ターゲット サーバーのホスト エイリアスを確認できます。

    3. ターゲット サーバーのホスト エイリアスが仮想ホストのエイリアスを指している場合、プロキシ チェーンです。この場合は、502 Bad Gateway エラーの実際の原因を特定するまで、チェーン プロキシに対して上記の手順をすべて繰り返す必要があります。
    4. ターゲット サーバー ホスト エイリアスがバックエンド サーバーを指している場合、バックエンド サーバーが Apigee へのレスポンスで重複するヘッダーを送信していることを示します。

NGINX

NGINX アクセスログを使用してエラーを診断するには:

  1. Private Cloud ユーザーの場合は、NGINX アクセスログを使用して、HTTP 502 エラーに関する重要な情報を特定できます。
  2. NGINX アクセスログを確認します。

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    説明: ORGENVPORT# は実際の値に置き換えます。

  3. 特定の期間に 502 エラーが発生したかどうか(問題が過去に発生した場合)、または 502 で失敗したリクエストがまだあるかどうかを検索します。
  4. X-Apigee-fault-code protocol.http.DuplicateHeader の値と一致する 502 エラーが見つかった場合は、X-Apigee-fault-source の値を特定します。

    NGINX アクセスログの 502 エラーの例:

    上記の NGINX アクセスログのエントリ例では、X-Apigee-fault-codeX-Apigee-fault-source に次の値が設定されています。

    レスポンス ヘッダー
    X-Apigee-fault-code protocol.http.DuplicateHeader
    X-Apigee-fault-source target

原因: レスポンスに重複したヘッダーがある

診断

  1. 一般的な診断手順で説明されているように、API Monitoring または NGINX アクセスログを使用して、観測されたエラーの障害コード障害の発生元を特定します。
  2. Fault Source の値が target の場合、ターゲット サーバーから送信されたレスポンスに重複するヘッダーが含まれていることを示します。
  3. 次のいずれかの方法で、レスポンスの一部として複数回送信される実際のヘッダーを特定できます。

    エラー メッセージ

    エラー メッセージの使用:

    1. Apigee Edge から受信した完全なエラー メッセージにアクセスできる場合は、faultstring を参照してください。faultstring には、複数回送信されたヘッダー名が含まれます。

      エラー メッセージの例:

      "faultstring":"Duplicate Header \"Expires\""
    2. 上記のエラー メッセージでは、faultstring に示されているように、ヘッダー Expires が複数回送信されていることがわかります。

    実際のリクエスト

    実際のリクエストを使用する場合:

    1. ターゲット サーバーに対して行われた実際のリクエストにアクセスできない場合は、Trace ツールを使用するの手順 10.a と手順 10.b から対応する curl コマンドを取得します。
    2. ターゲット サーバー アプリケーションに対して行われた実際のリクエストにアクセスできる場合は、次の操作を行います。

      1. ターゲット サーバーを呼び出します。

        この例で使用するターゲット サーバーのリクエストの例:

        curl -X GET "https://BACKEND_SERVER_HOST/response-headers?Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT&Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT" -v
        
      2. レスポンスに表示されるヘッダーのリストを確認します。

        この例で使用されているターゲット サーバーからのレスポンスのサンプル:

        * ...Trimmed...
        > GET /response-headers?Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT&Expires=Mon%2C%2021%20June%202021%2007%3A28%3A00%20GMT HTTP/2
        > Host: BACKEND_SERVER_HOST
        > User-Agent: curl/7.64.1
        > Accept: */*
        >
        * Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
        < HTTP/2 200
        < date: Fri, 02 Jul 2021 05:29:07 GMT
        < content-type: application/json
        < content-length: 166
        < server: gunicorn/19.9.0
        < Expires: Mon, 21 June 2021 07:28:00 GMT
        < Expires: Mon, 21 June 2021 07:28:00 GMT
        < access-control-allow-origin: *
        < access-control-allow-credentials: true
        <
        ----<Response BODY>------
        * Connection #0 to host httpbin.org left intact
        * Closing connection 0

        上記の例のリクエストでは、ヘッダー Expires が複数回送信されています。したがって、このリクエストは 502 Bad Gateway エラーとエラーコード protocol.http.DuplicateHeader で失敗します。

      3. faultstring に名前が表示されているヘッダーがバックエンド サーバーのレスポンスに複数回表示されている場合、それがこのエラーの原因です。上記のケースでは、ヘッダー Expires が複数回送信されます。

解決策

重複を修正する

オプション 1 [推奨オプション]: 重複するヘッダーを含まないようにバックエンド サーバーを修正する

  1. 特定のバックエンド サーバーが重複するヘッダー Expires を送信する理由を分析し、API プロキシがそれを受け入れてもよいかどうかを確認します。ほとんどの場合、HTTP 仕様 RFC7230 に準拠しないため、望ましくありません。
  2. 望ましくない場合は、重複するヘッダーを送信しないようにターゲット サーバー アプリケーションを変更します。上記の例では、ヘッダー Expires が同じ値で 2 回送信されていることがわかります。これは望ましくありません。この問題を解決するには、ターゲット サーバーが Expires ヘッダーを 1 回だけ渡すようにします。
  3. 重複するヘッダーを許可する場合は、オプション 2: CwC プロパティを使用するに進みます。

CwC

オプション 2: CwC プロパティを使用する

Apigee には、クライアント アプリケーションとターゲット サーバーが Apigee Edge の API プロキシに重複するヘッダーを送信できるようにする CwC プロパティ HTTPHeader.<HeaderName> が用意されています。

CwC プロパティ
HTTPHeader.<HeaderName> allowDuplicates,multivalued

たとえば、次のプロパティを Message Processor に設定すると、ヘッダー Expires の重複と複数の値を許可できます。

HTTPHeader.Expires=allowDuplicates, multiValued
  1. Private Cloud ユーザーの場合は、 重複するヘッダーを使用するようにメッセージ プロセッサを構成する入門ガイドを使用して、リクエストに重複するヘッダーが含まれていても Apigee Edge が 502 Bad Gateway エラーを発生させないようにプロパティを構成できます。
  2. Public Cloud ユーザーの場合は、Apigee Edge サポートに連絡して、組織のこのプロパティを構成してください。

仕様

Apigee は、バックエンド サーバーが次の RFC 仕様に従って動作することを想定しているため、502 Bad Gateway エラー レスポンスを返します。

仕様
RFC 7230、セクション 3.2.2: Field Order
RFC 7230、セクション 3.2: Header Fields

Apigee サポートのサポートが必要な場合は、 診断情報の収集が必要な場合をご覧ください。

診断情報の収集が必要な場合

次の診断情報を収集して、Apigee Edge サポートにお問い合わせください。

Public Cloud ユーザーの場合は、次の情報を提供してください。

  • 組織名
  • 環境名
  • API プロキシ名
  • 502 エラーを再現するために使用される完全な curl コマンド
  • API リクエストのトレース ファイル

Private Cloud ユーザーの場合は、次の情報を提供してください。

  • 失敗したリクエストで確認されたエラー メッセージの全文
  • 環境名
  • API プロキシ バンドル
  • API リクエストのトレース ファイル
  • NGINX アクセスログ:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    説明: ORGENVPORT# は実際の値に置き換えます。

  • Message Processor のシステムログ /opt/apigee/var/log/edge-message-processor/logs/system.log