500 Internal Server Error - BadFormData

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

内容

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

エラー メッセージ

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

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 ペアとして送信されます。

      フォームデータを使用したリクエストの例:

      curl https://HOSTALIAS/somepath -H "Content-Type: application/x-www-form-urlencoded" -d "username=abc@google.com&pasword=secret123"
      
    • キーと値の両方に含まれる英数字以外の文字は、 パーセント エンコードされます。つまり、パーセント記号と、特定の文字の ASCII コードを表す 2 つの 16 進数で構成される文字 3 要素 %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. [Analyze] > [API Monitoring] > [Investigate] ページに移動します。
  4. エラーが発生した期間を選択します。
  5. [Time] に [Fault Code] をプロットします。

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

    大きい画像を表示

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

    大きい画像を表示

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

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

Trace ツール

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

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

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

    上記のサンプル トレースで、EV-ExtractFormParams という名前の Extract Variables ポリシーでエラーが発生したことを確認します。

  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(Analytics Data Recorded)] フェーズに移動してクリックします。
  9. [Phase Details] - [Error Headers] セクションまで下にスクロールし、以下のように X-Apigee-fault-codeX-Apigee-fault-sourceX-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, です。これは、EV-ExtractFormParams という名前の Extract Variables ポリシーがフォーム パラメータの読み取りまたは抽出中に失敗したことを意味します。

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. protocol.http.BadFormData の値と一致する X-Apigee-fault-code500 エラーが見つかった場合は、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,X-Apigee-fault-policy,
  6. この例では、X-Apigee-fault-policyextractvariables/EV- ExtractFormParams, です。これは、EV-ExtractFormParams という名前の Extract Variables ポリシーがフォーム パラメータの読み取り中に失敗したことを意味します。

原因: リクエストのフォーム パラメータに使用できない文字が含まれています

診断

  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>
            

      上記の Extract Variables ポリシーで次の操作を行います。

      • 出典: request

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

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

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

      これは、クライアントが Apigee Edge に HTTP リクエストの一部として渡すフォーム パラメータ usernamepassword に、使用できない文字が含まれていることを示します。

      サンプル 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>
            

      上記の Extract Variables ポリシーで次の操作を行います。

      • ソース: request

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

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

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

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

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

    Trace ツール

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

    1. 一般的な診断手順の説明に沿って、失敗したリクエストのトレースをキャプチャした場合は、失敗したリクエストのいずれかを選択します。
    2. 使用が許可されていない文字を含むフォーム パラメータが、上記のステップ 3 で HTTP リクエストに含まれていると判断した場合は、
      1. Request Received from Client」フェーズに移動します。
      2. [Phase Details] セクションまで下にスクロールし、[Request Content] を確認します。

        拡大画像を表示

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

    実際のリクエスト

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

    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 は 500 Internal Server Error というエラーコード protocol.http.BadFormData を返します。

解像度

  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.BadFormData とともに 500 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

参照