400 Bad Request - DecompressionFailureAtRequest

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

内容

クライアント アプリケーションが、API 呼び出しへのレスポンスとして、HTTP ステータス コード 400 Bad Request とエラーコード messaging.adaptors.http.flow.DecompressionFailureAtRequest を受け取ります。

エラー メッセージ

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

HTTP/1.1 400 Bad Request

また、以下のようなエラー メッセージが表示される場合もあります。

{
   "fault":{
      "faultstring":"Decompression failure at request",
      "detail":{
         "errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtRequest"
      }
   }
}

考えられる原因

このエラーは、次の場合にのみ発生します。

  • HTTP リクエスト ヘッダー Content-Encoding で指定されたエンコードが有効であり、 Apigee Edge でサポートされている
  • ただし

  • HTTP リクエストの一部としてクライアントから送信されたペイロード形式が、Content-Encoding ヘッダーで指定されたエンコード形式と一致していない

これは、Apigee Edge が指定されたエンコードを使用してペイロードをデコードできないためです。ペイロードの形式が Content-Encoding ヘッダーで指定されたエンコードと異なるためです。

サポートされている Content-Encoding 値の例と、それらの場合のペイロード形式に対する Apigee Edge の想定を以下に示します。

シナリオ Content-Encoding 想定されるペイロード形式
単一のエンコード gzip

Unix の gzip 形式。

RFC1952 GZIP 形式をご覧ください。

単一のエンコード デフレート

この形式では、zlib 構造とデフレート圧縮アルゴリズムを使用します。

RFC1950 RFC1951 をご覧ください。.

複数のエンコード

複数のエンコード

たとえば、エンコードが 2 回行われる場合は次のようになります。

  • gzip、deflate
  • gzip、gzip
  • deflate、gzip
  • deflate、deflate
ヘッダーに表示されるとおりの順序で、複数のエンコードがペイロードに適用されます。

このエラーには、次のような原因が考えられます。

原因 説明 トラブルシューティングの実施対象
リクエスト ペイロードの形式が、Content-Encoding ヘッダーで指定されたエンコードと一致していない クライアントから送信されたリクエスト ペイロードの形式がエンコードされていないか、Content-Encoding ヘッダーで指定されたエンコードと一致していません。 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. 次のように、障害コード messaging.adaptors.http.flow.DecompressionFailureAtRequest を含むセルを選択します。

    拡大画像を表示

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

    拡大画像を表示

  9. [ログを表示] をクリックし、400 エラーで失敗した行を開きます。

    拡大画像を表示

  10. [ログ] ウィンドウで、次の詳細をメモします。
    • ステータス コード: 400
    • 障害ソース: proxy
    • 障害コード: messaging.adaptors.http.flow.DecompressionFailureAtRequest
  11. [Fault Source] の値が proxy の場合、リクエスト ペイロードの形式が Content-Encoding ヘッダーで指定された サポートされているエンコードと一致しなかったことを示します。

Trace ツール

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

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

  3. 失敗したリクエストの 1 つを選択し、トレースを調べます。
  4. トレースのさまざまなフェーズを確認し、エラーが発生した場所を特定します。
  5. 通常、エラーは次に示すように、Request Received from Client フェーズの直後のフローで発生します。

    拡大画像を表示

  6. トレースのプロパティの値をメモします。

    • エラー: Decompression failure at request
    • error.class: com.apigee.rest.framework.BadRequestException
    • error.cause: Not in GZIP format

    error.cause には、リクエスト ペイロードが GZIP 形式ではないことを示しています。これは、Apigee Edge が Content-Encoding ヘッダーで指定されたリクエスト ペイロードの GZIP 形式を想定していたことを意味します。

  7. リクエスト ヘッダー Content-Encoding の値を特定します。その場合は、次のように [Request Received from Client] フェーズに移動します。

    拡大画像を表示

    リクエスト ヘッダー Content-Encoding の値は実際に gzip です。

    上記のサンプル トレースは、リクエスト ヘッダー Content-Encoding で指定されたエンコードが gzip であることを示しています。ただし、リクエスト ペイロードは GZIP 形式ではありません。したがって、Apigee は gzip を使用してペイロードを解凍できず、エラー Decompression failure at request を返します。

  8. 移動して Apigee Edge から返されるステータス コードとエラー メッセージに注意します。

    次のようにトレースの Response Sent to Client フェーズに送信されます。

    拡大画像を表示

    トレースで次の詳細に注意してください。

    • ステータス コード: 400 Bad Request
    • エラー内容: {"fault":{"faultstring":"Decompression failure at request","detail":{"errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtRequest"}}}
  9. トレースの AX(Analytics Data Recorded)フェーズに移動し、クリックします。

  10. [Phase Details] と [Error Headers] のセクションまで下にスクロールし、次のように X-Apigee-fault-codeX-Apigee-fault-source の値を確認します。

    拡大画像を表示

  11. X-Apigee-fault-codeX-Apigee-fault-source の値が messaging.adaptors.http.flow.DecompressionFailureAtRequestpolicy として表示されます。これらは、リクエスト ペイロードの形式が Content-Encoding ヘッダーで指定されたエンコードと一致していないことを示します。
    レスポンス ヘッダー
    X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtRequest
    X-Apigee-fault-source policy

NGINX

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

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

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

    ここでORGENVPORT# は実際の値に置き換えられます。

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

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

    上記の NGINX アクセスログのエントリ例では、X-Apigee-fault-code X-Apigee-fault-code に次の値が入っています。

    レスポンス ヘッダー
    X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtRequest
    X-Apigee-fault-source policy

原因: リクエスト ペイロードの形式が、Content-Encoding ヘッダーで指定されたエンコードと一致していない

デフォルトでは、リクエスト ヘッダー Content-Encoding に有効な サポートされているエンコードが含まれている場合、Apigee Edge は常にペイロードを解凍します。したがって、リクエスト ペイロードの形式は、リクエスト ヘッダー Content-Encoding で指定されたエンコードと一致する必要があります。不一致があると、このエラーが発生します。

診断

  1. 一般的な診断手順で説明されているように、API Monitoring、Trace ツール、または NGINX アクセスログを使用して確認されたエラーの障害コード障害ソースを特定します。
  2. 障害コードmessaging.adaptors.http.flow.DecompressionFailureAtRequest で、[Fault Source] の値が policy または proxy の場合、クライアント アプリケーションから送信されたリクエストに、リクエスト ヘッダー Content-Encoding で指定された サポートされているエンコードと一致しないペイロードがあることを示します。
  3. 次のいずれかの方法を使用して、HTTP リクエストの一部として不一致を判断できます。

    エラー メッセージ

    エラー メッセージを使用して検証するには:

    1. Apigee Edge から受信した完全なエラー メッセージにアクセスできる場合は、faultstring を参照してください。

      エラー メッセージの例:

      "faultstring":"Decompression failure at request"
      
    2. 上記のエラー メッセージには "Decompression failure at request" が表示されます。これは、Content-Encoding ヘッダーで指定されたエンコードを使用してリクエストを解凍できなかったことを示しています。

    Trace

    Trace を使用して検証するには:

    1. 一般的な診断手順で説明されているように、Trace を使用して、リクエスト ヘッダー Content-Encoding の値とプロパティ error.cause を特定します。
    2. サンプル トレースの値は次のとおりです。

      • Content-Encoding: gzip
      • error.cause: Not in GZIP format

      リクエスト ヘッダー Content-Encoding の値は gzip です。ただし、リクエスト ペイロードは GZIP 形式ではありませんerror.cause で示されています)。したがって、Apigee Edge は 400 Bad Request とエラーコード messaging.adaptors.http.flow.DecompressionFailureAtRequest を返します。

    実際のリクエスト

    実際のリクエストを使用して検証するには:

    クライアント アプリケーションによって行われた実際のリクエストにアクセスできる場合は、次の手順を行います。

    1. リクエスト ヘッダー Content-Encoding に渡される値を特定します。
    2. リクエストの一部として送信されるペイロードの形式を決定します。
    3. Content-Encoding ヘッダーの値が サポートされているエンコードのリストに含まれているにもかかわらず、リクエスト ペイロードの形式が Content-Encoding ヘッダーで指定されたエンコードと一致しない場合、これが問題の原因です。

      リクエストの例:

      curl -v "http://HOSTALIAS/v1/testgzip" -H "Content-Encoding: gzip" -X POST -d @request_payload.zip
      

      上記のサンプル リクエストでは、値 gzipContent-Encoding ヘッダーに送信します。これは Apigee Edge で サポートされているエンコードです。ただし、リクエスト ペイロード request_payload.zip は ZIP 形式です。このため、このリクエストは 400 Bad Request ステータス コードとエラーコード messaging.adaptors.http.flow.DecompressionFailureAtRequest で失敗します。

    Message Processor のログ

    Message Processor のログを使用して検証するには:

    Private Cloud ユーザーの場合は、Message Processor のログを使用して、HTTP 400 エラーに関する重要な情報を特定できます。

    1. 一般的な診断手順で説明されているように、API Monitoring、Trace ツール、または NGINX アクセスログを使用して、失敗したリクエストのメッセージ ID を特定します。
    2. Message Processor ログでメッセージ ID を検索します。

      /opt/apigee/var/log/edge-message-processor/logs/system.log

    3. 次のいずれかの例外が表示されます。

      シナリオ #1

      シナリオ 1: API リクエストに Content-Encoding: gzip ヘッダーがある場合

      2021-07-28 10:21:16,861  NIOThread@0 ERROR HTTP.SERVER -
      HTTPServer$Context.onInputException() : Message id:rt-57-1
      SSLClientChannel[Accepted: Remote:192.168.199.8:8443
      Local:192.168.80.234:44284]@28469 useCount=1 bytesRead=0
      bytesWritten=28764 age=2739893ms  lastIO=0ms
      isOpen=true.onExceptionRead exception: {}
      java.util.zip.ZipException: Not in GZIP format
      
      2021-07-28 10:21:16,862  NIOThread@0 ERROR ADAPTORS.HTTP.FLOW -
      AbstractRequestListener.onException() : Request:POST, uri:/test,
      message Id:rt-57-1, exception:java.util.zip.ZipException: Not in GZIP format,
      context:Context@71ea5ac input=ClientInputChannel(SSLClientChannel[Accepted:
      Remote:192.168.199.8:8443 Local:192.168.80.234:44284]@28469 useCount=1
      bytesRead=0 bytesWritten=28764 age=2739894ms  lastIO=0ms  isOpen=true)
      2021-07-28 10:21:16,862  NIOThread@0 INFO  HTTP.SERVICE -
      ExceptionHandler.handleException() :
      Exception java.util.zip.ZipException: Not in GZIP format occurred while writing
      to channel null
      2021-07-28 10:21:16,863  NIOThread@0 INFO  HTTP.SERVICE -
      ExceptionHandler.handleException() : Exception trace:
      java.util.zip.ZipException: Not in GZIP format
      

      上記のエラー メッセージの java.util.zip.ZipException: Not in GZIP format 行は、Content-Encoding が gzip として指定されているにもかかわらず、リクエスト ペイロードが GZIP 形式で送信されないことを示しています。したがって、Apigee Edge は例外をスローし、400 ステータス コードと障害コード messaging.adaptors.http.flow.DecompressionFailureAtRequest をクライアント アプリケーションに返します。

      シナリオ #2

      シナリオ 2: API リクエストに Content-Encoding: deflate ヘッダーがある場合

      2021-07-28 15:26:31,893  NIOThread@1 ERROR HTTP.SERVER -
      HTTPServer$Context.onInputException() : Message id:rt-47875-1
      SSLClientChannel[Accepted: Remote:192.168.199.8:8443
      Local:192.168.81.72:45954]@29276 useCount=1 bytesRead=0
      bytesWritten=37230 age=3498856ms  lastIO=1ms
      isOpen=true.onExceptionRead exception: {}
      java.util.zip.ZipException: incorrect header check
                        ….
      Caused by: java.util.zip.DataFormatException: incorrect header check
             ..
      2021-07-28 15:26:31,894  NIOThread@1 ERROR ADAPTORS.HTTP.FLOW -
      AbstractRequestListener.onException() : Request:POST, uri:/test,
      message Id:rrt-47875-1, exception:java.util.zip.ZipException:
      incorrect header check, context:Context@69b3ac45
      input=ClientInputChannel(SSLClientChannel[Accepted:
      Remote:192.168.199.8:8443 Local:192.168.81.72:45954]@29276
      useCount=1 byt	esRead=0 bytesWritten=37230 age=3498856ms
      lastIO=1ms  isOpen=true)
      

      上記のエラー メッセージの java.util.zip.ZipException: incorrect header check 行と Caused by: java.util.zip.DataFormatException: incorrect header check 行は、リクエスト ペイロードが deflate 形式で送信されず、deflate の Content-Encoding ヘッダーで指定されたエンコードと一致していないことを示します。したがって、Apigee Edge は例外をスローし、400 ステータス コードと障害コード messaging.adaptors.http.flow.DecompressionFailureAtRequest をクライアント アプリケーションに返します。

解像度

  1. Apigee Edge の API プロキシフローとバックエンド サーバーで圧縮リクエスト ペイロードを必要としない場合は、ヘッダー Content-Encoding渡さないでください。リクエスト ペイロードを圧縮する必要がある場合は、ステップ 2 に進みます。
  2. クライアント アプリケーションが常に以下を送信することを確認します。
    • リクエスト内の Content-Encoding ヘッダーの値として、 サポートされているエンコードのいずれか
    • Apigee Edge に対してサポートされている形式のリクエスト ペイロードが、Content-Encoding ヘッダーで指定されたエンコード形式と一致する
  3. 上記の例では、リクエスト ペイロードは ZIP 形式ですが、リクエスト ヘッダーでは Content-Encoding: gzip が指定されています。この問題を解決するには、リクエスト ヘッダーを Content-Encoding: gzip として送信し、リクエスト ペイロードを gzip 形式でも送信します。
    curl -v "https://HOSTALIAS/v1/testgzip" -H "Content-Encoding: gzip" -X POST -d @request_payload.gz
    

仕様

Apigee Edge は、次の RFC 仕様に従って、エラーコード messaging.adaptors.http.flow.DecompressionFailureAtRequest とともにステータス コード 400 Bad Request を返します。

仕様
RFC 7231、セクション 6.5.1
RFC 7231、セクション 3.1.2.2

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

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

次の診断情報を収集して、Apigee Edge サポートに連絡してください。

Public Cloud ユーザーの場合は、次の情報を入力します。

  • 組織の名前
  • 環境名
  • API プロキシ名
  • 400 エラーを再現するための完全な 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