502 Bad Gateway - 重複ヘッダー

現在、Apigee Edge のドキュメントを表示しています。
Apigee X のドキュメントをご確認ください
情報

内容

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

エラー メッセージ

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

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: フィールドの順序 に従い、送信者は、そのヘッダー フィールドのフィールド値全体がカンマ区切りのリストとして定義されている場合を除き、メッセージ内で同じフィールド名を持つ複数のヘッダー フィールドを生成してはなりません。#(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. [Time] に [Fault Code] をプロットします。
  7. 以下に示すように、障害コード protocol.http.DuplicateHeader のセルを選択します。

    大きい画像を表示

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

    大きい画像を表示

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

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

Trace ツール

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

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

  3. 失敗したリクエストの 1 つを選択し、トレースを調べます。
  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-code と X-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」サーバー フェーズに戻ります。[Show 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 X-Apigee-fault-code の値と一致する 502 エラーが見つかった場合は、X-Apigee-fault-code の値を特定します。

    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. ターゲット サーバーに対して行われた実際のリクエストにアクセスできない場合は、ステップ 10.a とステップ 10.b の Trace ツールの使用で、対応する 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 が提供する CwC プロパティ HTTPHeader.<HeaderName> を使用すると、クライアント アプリケーションとターゲット サーバーは、重複するヘッダーを Apigee Edge の API プロキシに送信できます。

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

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

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

仕様

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

仕様
RFC 7230 のセクション 3.2.2: フィールドの順序
RFC 7230、セクション 3.2: ヘッダー フィールド

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