400 Bad Request - DecompressionFailureAtRequest

ここに表示されているのは Apigee Edge のドキュメントです。
Go to the Apigee X のドキュメントに移動します。
info

症状

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

エラー メッセージ

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

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 ヘッダーで指定されたエンコード形式と一致していません

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

サポートされている Content-Encoding 値の例と、Apigee Edge がペイロード形式を想定するケースをいくつか示します。

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

Unix の gzip 形式。

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

単一エンコード deflate

この形式では、deflate 圧縮アルゴリズムで 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. [分析] > [API Monitoring] > [調査] ページに移動します。
  4. エラーが発生した特定の期間を選択します。
  5. [プロキシ] フィルタが [すべて] に設定されていることを確認します。
  6. [障害コード] を [時間] に対してプロットします。
  7. 次のように、障害コード messaging.adaptors.http.flow.DecompressionFailureAtRequest を含むセルを選択します。

    ( 大きい画像を表示)

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

    ( 大きい画像を表示)

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

    ( 大きい画像を表示)

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

Trace ツール

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

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

  3. 失敗したリクエストのいずれかを選択して、トレースを調べます。
  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 がリクエスト ペイロードを GZIP 形式で想定していたことを意味します Content-Encoding ヘッダーで指定されているように。

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

    ( 大きい画像を表示)

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

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

  8. 次のようにトレースの [**Response Sent to Client**] フェーズに移動して、Apigee Edge から返されたステータス コードとエラー メッセージを確認します。

    トレース内の以下のクライアントに送信された応答フェーズまで:

    ( 大きい画像を表示)

    トレースから次の詳細を確認します。

    • ステータス コード: 400 Bad Request。
    • エラー コンテンツ: {"fault":{"faultstring":"Decompression failure at request","detail":{"errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtRequest"}}}
  9. トレースの [AX](Analytics データが記録されました)フェーズに移動してクリックします。

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

    ( 大きい画像を表示)

  11. X-Apigee-fault-code と X-Apigee-fault-source の値は messaging.adaptors.http.flow.DecompressionFailureAtRequest と policy であり、リクエスト ペイロードの形式が 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

    ここで: ORG、ENV、PORT# は実際の値に置き換えてください。

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

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

    NGINX アクセスログの上のサンプル エントリには、 X-Apigee-fault-code と X-Apigee-fault-source の値が次のように設定されています。

    レスポンス ヘッダー 値
    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 で、 障害の発生源 の値が policy または proxy の場合、クライアント アプリケーションから送信されたリクエストに、リクエスト ヘッダー Content-Encoding で指定された サポート対象のエンコードと一致しないペイロードが含まれていることを示します。
  3. 次のいずれかの方法で、HTTP リクエストの一部として不一致を特定できます。 メソッド:

    エラー メッセージ

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

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

      エラー メッセージの例:

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

    トレース

    トレースを使用して検証するには:

    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
      

      上記のリクエスト例では、値 gzip が Content-Encoding ヘッダーに送信されます。これは、 サポートされているエンコード です。ただし、リクエスト ペイロード 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 は、リクエスト ペイロードが GZIP 形式で送信されていないことを示しています。ただし、Content-Encoding は gzip として指定されています。そのため、Apigee Edge は例外をスローし、 障害コード messaging.adaptors.http.flow.DecompressionFailureAtRequest を含む 400 ステータス コードをクライアント アプリケーションに返します。

      シナリオ #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 は例外をスローし、障害コード messaging.adaptors.http.flow.DecompressionFailureAtRequest を含む 400 ステータス コードをクライアント アプリケーションに返します。

解決策

  1. Apigee Edge とバックエンド サーバーの API プロキシ フローで圧縮されたリクエスト ペイロードが必要ない場合は、渡さないでください。Content-Encoding リクエスト ペイロードを圧縮する必要がある場合は、ステップ 2 に進みます。
  2. クライアント アプリケーションが常に次のものを送信するようにします。
  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

    ここで: ORG、ENV、PORT# は実際の値に置き換えてください。

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