500 Internal Server Error - BadFormData

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

症状

クライアント アプリケーションが、API 呼び出しに対するレスポンスとしてエラーコード protocol.http.BadFormData を含む HTTP ステータス コード 500 Internal Server Error を受け取ります。

エラー メッセージ

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

HTTP/1.1 500 Internal Server Error

さらに、次のエラー メッセージも確認できます。

{
   "fault":{
      "faultstring":"Bad Form Data",
      "detail":{
         "errorcode":"protocol.http.BadFormData"
      }
   }
}

フォームデータ

この問題のトラブルシューティングの詳細に入る前に、フォームデータについて説明します。

フォームデータは、通常、テキスト入力ボックス、ボタン、チェックボックスなどの要素を含む HTML フォームを介してユーザーが提供する情報です。フォームデータは通常、HTTP リクエストまたはレスポンスの一部として、一連の Key-Value ペアとして送信されます。

フォームデータの送信

  1. Content-Type: application/x-www-form-urlencoded
    • フォームデータのサイズが小さい場合、データは Key-Value ペアとして送信されます。
      • 両方のキーの文字は、 フォーム - セクション 17.13.4.1で説明されているルールに従ってエンコードされます。
      • ヘッダー Content-Type: application/x-www-form-urlencoded

      フォームデータを含むリクエストの例:

      curl https://HOSTALIAS/somepath -H "Content-Type: application/x-www-form-urlencoded" -d "username=abc@google.com&pasword=secret123"
      
    • 両方のキーと値の英数字以外の文字は パーセント エンコードされます。つまり、特定の文字の ASCII コードを表す 2 桁の 16 進数に続くパーセント記号で構成される文字トリプレット %HHとして表されます。
    • したがって、パーセント記号(%)はフォームデータで使用できますが、特別なエスケープ シーケンスの開始として解釈されます。そのため、フォームデータのキーまたは値にパーセント記号(%)を含める必要がある場合は、パーセント記号(%)文字の ASCII コードを表す %25, として送信する必要があります。
  2. Content-Type: multipart/form-data

    大量のバイナリデータまたは ASCII 以外の文字 を含むテキストを送信する場合は、 フォーム - セクション 17.13.4.2 で説明されているように、 Content-Type: multipart/form-data を使用して データを送信できます。

考えられる原因

このエラーは、次のすべての条件が満たされた場合にのみ発生します。

  1. クライアントが Apigee Edge に送信する HTTP リクエスト に以下が含まれる。
    1. Content-Type: application/x-www-form-urlencoded、および
    2. パーセント記号(%)付き、またはパーセント記号 (%)の後に フォーム - セクション 17.13.4.1によって許可されていない無効な 16 進数文字が続くフォームデータ。
  2. Apigee Edge の API プロキシは、リクエスト フローで ExtractVariables ポリシーまたは AssignMessage ポリシーを使用して、許可されていない 文字を含む特定のフォーム パラメータを読み取ります。

    たとえば、フォームデータにパーセント記号(%)がそのまま(エンコードなしで)含まれている場合、またはパーセント記号(%の後にキーや値に無効な 16 進数文字が続く場合は、このエラーが発生します。

    このエラーの原因として考えられるのは次のとおりです。

    原因 説明 トラブルシューティングの実施対象
    リクエストのフォーム パラメータに許可されていない文字が含まれている クライアントから HTTP リクエストの一部として渡されたフォーム パラメータに、使用が許可されていない 文字が含まれています。 Edge Public Cloud と Private Cloud のユーザー

共通の診断手順

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

API Monitoring

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

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

  3. [分析] > [API Monitoring] > [調査] ページに移動します。
  4. エラーが発生した特定の期間を選択します。
  5. [障害コード] を [時間] に対してプロットします。

  6. 次のように、障害コード protocol.http.BadFormData を含むセルを選択します。

    大きい画像を表示

  7. 障害コード protocol.http.BadFormData に関する情報が 表示されます。

    大きい画像を表示

  8. [ログを表示] をクリックし、失敗したリクエストの行を展開します。

  9. [ログ] ウィンドウで、次の詳細をメモします。
    • ステータス コード: 500
    • 障害の発生源: proxy
    • 障害コード: protocol.http.BadFormData
    • 障害ポリシー: extractvariables/EV-ExtractFormParams
  10. **障害の発生源** が proxy、**障害コード** が protocol.http.BadFormData、**障害ポリシー** が空でない場合、**障害ポリシー** で示された特定のポリシーが、使用が**許可されていない** 文字を含むフォームデータ(フォーム パラメータ)を読み取りまたは抽出しているときにエラーが発生したことを示します。
  11. この例では、X-Apigee-fault-policyextractvariables/EV- ExtractFormParams, です。これは、ExtractVariables ポリシー という名前の EV-ExtractFormParams が、フォーム パラメータの読み取りまたは抽出中に失敗したことを意味します。

Trace ツール

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

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

  3. 失敗したリクエストのいずれかを選択し、トレースを調べます。
  4. トレースのさまざまなフェーズを確認し、エラーが発生した場所を特定します。
  5. 通常、エラーは次のようにいずれかのポリシーにあります。

    上記のトレース例では、 EV-ExtractFormParams という名前の ExtractVariables ポリシーでエラーが発生しています。

  6. 失敗した特定のポリシーの後に、Error という名前のフローに移動します。

  7. トレースから次の値をメモします。

    エラー: Bad Form Data

    状態: PROXY_REQ_FLOW

    error.class: com.apigee.rest.framework.BadRequestException

    • エラー Bad Form Data の値は、フォーム パラメータに使用が許可されていない 文字が含まれていることを示します。
    • 状態 PROXY_REQ_FLOW, の値は、 API プロキシの リクエスト フロー でエラーが発生したことを示します。
  8. トレースの [AX](記録された分析データ)フェーズに移動してクリックします。
  9. [**フェーズの詳細**] \- [**エラー ヘッダー**] セクションまでスクロールし、 次のように X-Apigee-fault-codeX-Apigee-fault-source、 および X-Apigee-fault-policy の値を特定します。

  10. X-Apigee-fault-codeX-Apigee-fault-source の値はそれぞれ protocol.http.BadFormDatapolicy であり、 X-Apigee-fault-policy は空ではありません。これは、 X-Apigee-fault-policy で示された特定のポリシーが、使用が 許可されていない 文字を含むフォームデータ(フォーム パラメータ)を読み取りまたは抽出しているときにエラーが発生したことを示します。

    レスポンス ヘッダー
    X-Apigee-fault-code protocol.http.BadFormData
    X-Apigee-fault-source policy
    X-Apigee-fault-policy extractvariables/EV-ExtractFormParams
  11. この例では、X-Apigee-fault-policyextractvariables/EV- ExtractFormParams, です。これは、ExtractVariables ポリシー EV-ExtractFormParams が、フォーム パラメータの読み取りまたは抽出中に失敗したことを意味します。

NGINX

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

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

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

  3. 特定の期間(過去に問題が発生した場合)にエラーコード protocol.http.BadFormData500 エラーが発生しているかどうか、または 500 で失敗しているリクエストがまだあるかどうかを確認します。
  4. X-Apigee-fault-codeprotocol.http.BadFormData の値と一致する 500 エラーが見つかった場合は、X-Apigee-fault-sourceX-Apigee-fault-policy の値を特定します。

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

    NGINX アクセスログの上のサンプル エントリには、 X-Apigee-fault-codeX-Apigee-fault-source: の次の値があります。

    ヘッダー
    X-Apigee-fault-code protocol.http.BadFormData
    X-Apigee-fault-source policy
    X-Apigee-fault-policy extractvariables/EV-ExtractFormParams
  5. X-Apigee-fault-codeX-Apigee-fault-source の値はそれぞれ protocol.http.BadFormDatapolicy であり、X-Apigee-fault-policy は空ではありません。これは、 X-Apigee-fault-policy で示された特定のポリシーが、 使用がX-Apigee-fault-policy, 文字を含むフォームデータ(フォーム パラメータ)を読み取りまたは抽出しているときにエラーが発生したことを示します。
  6. この例では、X-Apigee-fault-policyextractvariables/EV- ExtractFormParams, です。これは、ExtractVariables ポリシー という名前のEV-ExtractFormParams が、フォーム パラメータの読み取り中に失敗したことを意味します。

原因: リクエストのフォーム パラメータに許可されていない文字が含まれている

診断

  1. 共通の診断手順で説明されているように、API Monitoring、Trace ツール、NGINX アクセスログを使用して、500 Internal Server Error障害コード障害の発生源障害ポリシー を特定します。
  2. **障害コード**protocol.http.BadFormData**障害の発生源** の値が proxy または policy、**障害ポリシー** が空でない場合 これは、**障害ポリシー** で指定されたポリシーがフォームデータ(フォーム パラメータ)の読み取りまたは抽出中に失敗したことを示します。
  3. 障害ポリシー で示されたポリシーを調べて、次の情報を特定します。
    1. ソース: ポリシーが リクエストまたはレスポンスからデータを読み取りまたは抽出しているかどうかを判断します。
    2. フォーム パラメータ: ポリシーで読み取られる特定のフォーム パラメータを特定します。

      サンプル 1

      サンプル 1: フォーム パラメータを抽出する ExtractVariables ポリシー:

            <ExtractVariables name="EV-ExtractFormParms">
               <DisplayName>EV-ExtractFormParams</DisplayName>
               <Source>request</Source>
               <FormParam name="username">
                  <Pattern ignoreCase="false">{username}</Pattern>
               </FormParam>
               <FormParam name="password">
                 <Pattern ignoreCase="false">{password}</Pattern>
               </FormParam>
               <VariablePrefix>forminfo</VariablePrefix>
             <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
            </ExtractVariables>
            

      上記の ExtractVariables ポリシーでは:

      • ソース: request

        これは <Source> 要素で示されます。

      • フォーム パラメータ: usernamepassword

        これは、 要素内の<Pattern> <FormParam>要素で示されます。

      これは、クライアントから Apigee Edge への HTTP リクエスト の一部として渡されたフォーム パラメータ username または password に、使用が 許可されていない 文字が含まれていることを示します。

      サンプル 2

      サンプル 2: フォーム パラメータをコピーする AssignMessage ポリシー:

            <AssignMessage continueOnError="false" enabled="true" name="AM-CopyFormParams">
              <Copy source="request">
                <FormParams>
                  <FormParam name="username"/>
                  <FormParam name="password"/>
                </FormParams>
              </Copy>
              <AssignTo createNew="true" transport="http" type="request"/>
            </AssignMessage>
            

      上記の ExtractVariables ポリシーでは:

      • ソース: request

        これは、source 属性が <Copy> 要素で示されます。

      • フォーム パラメータ: usernamepassword

        これは、name 属性の <FormParam> 要素で示されます。

      これは、クライアントから Apigee Edge への HTTP リクエスト の一部として渡されたフォーム パラメータ username または password または その両方に、使用が許可されていない 文字が含まれていることを示します。

  4. 次のいずれかの方法を使用して、ステップ 3 で特定したフォーム パラメータに、使用が許可されていない 文字が含まれているかどうかを確認します。

    Trace ツール

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

    1. 共通の診断手順で説明されているように、失敗したリクエストのトレースをキャプチャした場合は、失敗したリクエストのいずれかを選択します。
    2. ステップ 3 で、使用が許可されていない 文字を含むフォーム パラメータが HTTP リクエストの一部であることが判明した場合は、
      1. フェーズ [Request Received from Client] に移動します。
      2. [フェーズの詳細] セクションまでスクロールし、 [リクエスト コンテンツ] を確認します。

        大きい画像を表示

      3. 上記の例では、フォーム パラメータ password にパーセント記号(%)が含まれています。
      4. パーセント記号(%)は特殊文字の パーセント エンコードにも使用されるため、フォームデータでそのまま使用することはできません。
      5. そのため、Apigee Edge はエラーコード protocol.http.BadFormData を含む 500 Internal Server Error を返します。

    実際のリクエスト

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

    1. ターゲット サーバーに対して行われた実際のリクエストにアクセスできない場合は、 解決策に進みます。
    2. Apigee Edge に対して行われた実際のリクエストにアクセスできる場合は、次の手順を行います。
      1. フォームデータの内容を確認し、 使用が許可されていない 文字(パーセント記号(%)やパーセント記号(% の後に無効な 16 進数文字が続くなど)が含まれているかどうかを確認します。

        サンプル 1

        リクエストのサンプル 1: リクエストの一部としてのフォームデータ

        curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=123456abc123&client_secret=c23578%ZY"
        

        この例では、要素 client_secret にパーセント記号(%)の後に 無効な 16 進数文字 ZY が含まれています。

        サンプル 2

        リクエストのサンプル 2: ファイルで渡されたフォームデータ:

        curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d @form_data.xml
        

        form_data.xml の内容:

        xml=<user><username>abc1234@google.com</username><password>qwerty12345!@#$%</password></user>

        この例では、要素 password にパーセント記号(%)が含まれています。これは、フォームデータでそのまま渡すべきではありません。

    3. 上記の 2 つの例では、Apigee Edge への HTTP リクエストの一部として送信されたフォームデータに、使用が許可されていない 文字が含まれています。
    4. そのため、Apigee Edge はエラーコード protocol.http.BadFormData を含む 500 Internal Server Error を返します。

解決策

  1. クライアントから HTTP リクエストの一部として送信されるフォームデータまたはパラメータのキーと値の両方の特殊文字が、 フォームデータ - application/x-www-form-urlencoded で説明されているように常にエンコードされていることを確認します。
  2. 上記で説明した例では、次のように問題を解決できます。

    サンプル 1

    サンプル 1: リクエストの一部として渡されたフォームデータ:

    特定の文字の ASCII コードに一致する有効な 16 進数文字を使用します。 たとえば、ドル記号($)を送信する場合は、次のように %24 を使用します。

    curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=123456abc123&client_secret=c23578%24"
    

    サンプル 2

    リクエストのサンプル 2: ファイルで渡されたフォームデータ:

    curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d @form_data.xml
    

    form_data.xml の内容:

    パーセント記号(%)にパーセント エンコードを使用します。つまり、次のようにファイルが %25 になるように変更します。

    xml=<user><username>abc1234@google.com</username><password>qwerty12345!!@#$%25</password></user>

仕様

Apigee Edge では、フォームデータ が次の仕様に従って送信されることが想定されています。

仕様
フォームデータ - application/x-www-form-urlencoded

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

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

上記の手順でも問題が解決しない場合は、次の 診断情報を収集して Apigee Edge サポートにお問い合わせください。

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

  • 組織名
  • 環境名
  • API プロキシの名前
  • エラーコード protocol.http.BadFormData500 Internal Server Error を再現するために使用した完全な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

参照