500 Internal Server Error - EmptyPath

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

内容

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

エラー メッセージ

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

HTTP/1.1 500 Internal Server Error

また、次のエラー メッセージが表示される場合があります。

{
   "fault":{
      "faultstring":"Request path cannot be empty",
      "detail":{
         "errorcode":"protocol.http.EmptyPath"
      }
   }
}

考えられる原因

このエラーは、フロー変数 target.url で表されるバックエンド サーバーのリクエスト URL に空のパスが含まれている場合に発生します。

RFC 3986 のセクション 3: 構文コンポーネント RFC 3986 のセクション 3.3: パスの仕様に従って、次のようになります。

  1. URI 構文 には次のコンポーネントがあります。

            foo://example.com:8042/over/there?name=ferret#nose
            \_/   \______________/\_________/ \_________/ \__/
             |            |            |            |       |
          scheme      authority       path        query   fragment
    
  2. path コンポーネントは必須です。パスの一部として他の文字がない場合でも、常にスラッシュ(/)を含まなければなりません。

したがって、バックエンド サーバーのリクエスト URL に path コンポーネントがまったくない場合、つまりスラッシュ(/)がない場合、Apigee Edge は 500 Internal Server Error とエラーコード protocol.http.EmptyPath を返します。

たとえば、target.url の値が https://www.mocktarget.apigee.net の場合、path コンポーネントが空か、欠落しているため、このエラーが発生します。

原因 説明 トラブルシューティングの実施対象
バックエンド サーバーの URL(target.url)のパスが空です フロー変数 target.url で表されるバックエンド サーバーの URL のパスが空です。 Edge Public Cloud ユーザーと Private Cloud ユーザー

共通の診断手順

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

API Monitoring

手順 1: API Monitoring の使用

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

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

  3. [Analyze] > [API Monitoring] > [Investigate] ページに移動します。
  4. エラーが発生した期間を選択します。
  5. [Time] に [Fault Code] をプロットします。

  6. 以下に示すように、障害コード protocol.http.EmptyPath のセルを選択します。

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

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

  9. [ログ] ウィンドウで、次の詳細をメモします。
    • ステータス コード: 500
    • 障害ソース: target
    • 障害コード: protocol.http.EmptyPath
  10. 障害ソースtarget で障害コードprotocol.http.EmptyPath の場合、バックエンド サーバーの URL に空のパスがあることを示します。

Trace

手順 2: Trace ツールを使用する

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

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

  3. 失敗したリクエストの 1 つを選択し、トレースを調べます。
  4. トレースのさまざまなフェーズを順に確認し、エラーが発生した場所を見つけます。
  5. このエラーは通常、以下に示すように、Target Request Flow Started フェーズ後のフローで発生します。

  6. トレースでのエラーの値をメモします。

    エラー: リクエストパスを空にすることはできません

    このエラーは、Target Request Flow Started フェーズの後で Apigee Edge によって発生するため、バックエンド サーバー URL の path であることを示しています。これは、リクエスト フローのいずれかのポリシーによってフロー変数 target.url(バックエンド サーバーの URL を表します)が空のパスで更新された可能性がある場合に発生する可能性があります。

  7. 各フローで、エラーポイントからTarget Request Flow Started フェーズに向けて逆方向に、各フローの「Variables Read and Assigned」セクションを確認してください。
  8. フロー変数 target.url が更新されるポリシーを決定します。

    JavaScript ポリシーがフロー変数 target.url を更新したことを示すトレースの例:

    上記のサンプル トレースで、SetTargetURL という名前の JavaScript ポリシーでフロー変数 target.url の値が次のように更新されます。

    target.url : https://mocktarget.apigee.net
    
  9. target.url には次のコンポーネントがあります。
    • スキーム: https://mocktarget.apigee.net
    • path:
  10. このため、Request path cannot be empty エラーが発生します。
  11. トレースの [AX(Analytics Data Recorded)] フェーズに移動してクリックします。
  12. [Phase Details] - [Error Headers] セクションまで下にスクロールし、次のように X-Apigee-fault-codeX-Apigee-fault-source の値を確認します。

  13. X-Apigee-fault-codeX-Apigee-fault-source の値がそれぞれ protocol.http.EmptyPathtarget として表示されます。これは、バックエンド サーバーの URL に空のパスがあるために、このエラーが生じたことを示しています。
    レスポンス ヘッダー
    X-Apigee-fault-code protocol.http.EmptyPath
    X-Apigee-fault-source target

NGINX

手順 3: 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.EmptyPath500 エラーが発生していないか(問題が過去に発生した場合)、または 500 で失敗しているリクエストがあるかどうかを検索します。
  4. X-Apigee-fault-code の値と一致する X-Apigee-fault-code 500 エラーが見つかった場合は、X-Apigee-fault-code の値を特定します。

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

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

    ヘッダー
    X-Apigee-fault-code protocol.http.EmptyPath
    X-Apigee-fault-source target

    X-Apigee-fault-codeX-Apigee-fault-source の値がそれぞれ protocol.http.EmptyPathtarget になっています。これは、バックエンド サーバーの URL に空のパスがあるために、このエラーが生じたことを示しています。

原因: バックエンド サーバーの URL(target.url)のパスが空です

診断

  1. 一般的な診断手順で説明されているように、API Monitoring、Trace ツール、または NGINX アクセスログを使用して、500 Internal Server Error障害コード障害ソースを特定します。
  2. 障害コードprotocol.http.EmptyPath で、[Fault Source] の値が target の場合、バックエンド サーバーの URL に空のパスがあることを示します。
  3. バックエンド サーバーの URL は、Apigee Edge のフロー変数 target.url で表されます。このエラーは通常、バックエンド サーバーの URL を更新しようとすると発生します。つまり、ターゲット リクエスト フロー内の(プロキシ/共有フロー内で)ポリシーを使用して、空のパスを持つポリシーを使用して、動的target.url を更新しようとした場合に発生します。

  4. フロー変数 target.url が実際に空のパスと、その値のソースを持っているかどうかを確認するには、次の操作を行います。

    Trace

    Trace ツールの使用

    このエラーのトレースをキャプチャしている場合は、Trace ツールの使用 で説明されている手順を実施し、以下を行います。

    1. target.url に空のパスがあるかどうかを確認します。
    2. 含まれている場合は、どのポリシーが空のパスを含むように target.url の値を変更または更新したかを確認します。

      JavaScript ポリシーがフロー変数 target.url: を更新したことを示すトレースの例

    3. 上記のサンプル トレースでは、JavaScript ポリシーによって target.url の値が変更または更新され、空のパスが含まれていることがわかります。
    4. target.url には次のコンポーネントがあります。
      • スキーム: https://mocktarget.apigee.net
      • path:

    ログ

    ログサーバーでのログの使用

    1. このエラー(断続的な問題)のトレースがない場合は、 MessageLogging ServiceCallout などのポリシーを使用して、フロー変数 target.url の値に関する情報をログサーバーに記録しているかどうかを確認します。
    2. ログがある場合は、それを確認し、次の操作を行います。
      1. target.url に空のパスがあるかどうかを確認します。
      2. 空のパスを含むように target.url を変更したポリシーを特定できるかどうかを確認する

    API プロキシ

    失敗した API プロキシの確認

    このエラーのトレースやログがない場合は、失敗した API プロキシを確認して、無効なパスを含むためにフロー変数 target.url を変更または更新した原因を特定します。次の点を確認します。

    • API プロキシ内のポリシー
    • プロキシから呼び出されるすべての共有フロー
  5. フロー変数 target.url を変更または更新する特定のポリシー(AssignMessage や JavaScript など)を調べて、target.url が空のパスに更新されている原因を特定します。

    次に、フロー変数 target.url に空のパスが誤って更新され、このエラーが発生するポリシーの例を示します。

    サンプル 1

    サンプル #1: JavaScript ポリシーで target.url 変数を更新する

    var url = "https://mocktarget.apigee.net"
    context.setVariable("target.url", url);
    

    上記のサンプルでは、フロー変数 target.url が、別の変数 url に含まれる値 https://mocktarget.apigee.net で更新されています。

    target.url には次のコンポーネントがあります。

    • スキーム: https://mocktarget.apigee.net
    • path:

    パスが空であるため、Apigee Edge は 500 Internal Server Error をエラーコード protocol.http.EmptyPath とともに返します。

    サンプル 2

    サンプル 2: JavaScript ポリシーで target.url 変数を更新する

    var path = context.getVariable("request.header.Path");
    var url = "https://mocktarget.apigee.net" + path
    context.setVariable("target.url", url);

    上記のサンプルでは、変数 url に含まれる値 https://mocktarget.apigee.net 別の変数 path(値は request.header.Path. から取得)を連結して、フロー変数 target.url が更新されます。

    実際のリクエストまたはトレースにアクセスできる場合は、request.header.Path に渡される実際の値を確認できます。

    ユーザーによるリクエストの例:

    curl -v https://HOST_ALIAS/v1/myproxy -H "Authorization: Bearer <token>
    

    この例では、ヘッダーパスはリクエストの一部として送信されません。したがって、JavaScript ポリシーの変数パスの値は null です。

    それによって次のようになります。

    • url = https://mocktarget.apigee.net + path
    • url = https://mocktarget.apigee.net + null
    • target.url = https://mocktarget.apigee.netnull

    target.url には次のコンポーネントがあります。

    • スキーム: https://mocktarget.apigee.netnull
    • path:

    サンプル 3

    サンプル #3: AssignMessage ポリシーで別の変数を使用して target.url 変数を更新する

    <AssignMessage async="false" continueOnError="false" enabled="true" name=">AM-SetTargetURL">
        <DisplayName>AM-SetTargetURL</DisplayName>
        <AssignVariable>
             <Name>target.url</Name>
             <Value>https://mocktarget.apigee.net</Value>
        </AssignVariable>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
        <AssignTo createNew="false" transport="http" type="request"/>
    </AssignMessage>
    

    target.url には次のコンポーネントがあります。

    • スキーム: https://mocktarget.apigee.net
    • path:

    上記の例では、バックエンド サーバーの URL のパス(target.url)が空であるため、Apigee Edge は 500 Internal Server Error をエラーコード protocol.http.EmptyPath とともに返します。

解決策

RFC 3986、セクション 2: 構文コンポーネントの仕様に従って、path コンポーネントは必須であり、path の一部として他の文字がない場合でも、常にスラッシュ(/)を含まなければなりません。この問題を解決するには、次の操作を行います。

  1. フロー変数 target.url で表されるバックエンド サーバーの URL には、常に空でないパスが含まれるようにします。
    1. 場合によっては、パスにリソース名が含まれない場合は、少なくともパスにスラッシュ(/)があることを確認してください。
    2. フロー変数 target.url の値を他の変数で決定する場合は、他の変数に空のパスがないようにします。
    3. フロー変数 target.url の値を決定するために文字列オペレーションを実行する場合は、文字列オペレーションの結果または結果に空のパスが含まれないようにします。
  2. 診断で説明したサンプルでは、以下のようにこの問題を解決できます。

    サンプル 1

    サンプル #1: JavaScript ポリシーで target.url 変数を更新する

    この問題を解決するには、次のように変数 url にスラッシュ(/)を追加します。

    var url = "https://mocktarget.apigee.net/"
    context.setVariable("target.url", url);
    

    サンプル 2

    サンプル 2: JavaScript ポリシーで target.url 変数を更新する

    var path = context.getVariable("request.header.Path");
    var url = "https://mocktarget.apigee.net" + path
    context.setVariable("target.url", url);
    

    この問題を解決するには、次のように有効なパス(例: /iloveapis)をリクエスト ヘッダー Path の一部として渡してください。

    リクエストの例:

    curl -v https://HOST_ALIAS/v1/myproxy -H "Authorization: Bearer <token> -H "Path: /iloveapis"
    

    サンプル 3

    サンプル #3: AssignMessage ポリシーで別の変数を使用して target.url 変数を更新する

    AssignMessage ポリシーの <Value> 要素に有効なパスを追加します。たとえば、MockTarget API のパスとして /json を使用できます。つまり、次のように <Value> 要素を https://mocktarget.apigee.net/json に変更します。

    <AssignMessage async="false" continueOnError="false" enabled="true" name="AM-SetTargetURL">
        <DisplayName>AM-SetTargetURL</DisplayName>
        <AssignVariable>
             <Name>target.url</Name>
             <Value>https://mocktarget.apigee.net/json</Value>
        </AssignVariable>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
        <AssignTo createNew="false" transport="http" type="request"/>
    </AssignMessage>
    

仕様

次の仕様に従い、Apigee Edge ではバックエンド サーバーの URL空のパスがないことを想定しています。

仕様
RFC 3986 のセクション 3: 構文コンポーネント
RFC 3986 のセクション 3.3: パス

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

診断情報の収集が必要

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

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

  • 組織の名前
  • 環境名
  • API プロキシ名
  • エラーコード protocol.http.EmptyPath500 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

参照

フロー変数 - ターゲット