500 Internal Server Error - EmptyPath

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

症状

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

エラー メッセージ

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

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: Syntax Components と RFC 3986、セクション 3.3: Pathに準拠しています。

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

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

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

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

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

トレース

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

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

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

  3. 失敗したリクエストのいずれかを選択し、トレースを調べます。
  4. トレースのさまざまなフェーズを調べて、障害が発生した場所を特定します。
  5. 通常、エラーは次のように [Target Request Flow Started] フェーズの後のフローにあります。

  6. トレースからエラーの値を確認します。

    error: Request path cannot be empty

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

  7. エラーポイントから [Target Request Flow Started] フェーズに向かって、各フローの [Variables Read and Assigned] セクションを調べます。
  8. フロー変数 target.url が更新されるポリシーを特定します。

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

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

    target.url : https://mocktarget.apigee.net
  9. target.url には次のコンポーネントが含まれます。
    • スキーム: https://mocktarget.apigee.net
    • パス: 空
  10. そのため、エラー Request path cannot be empty が発生します。
  11. トレースの [AX](記録された分析データ)フェーズに移動してクリックします。
  12. [Phase Details] - [Error Headers] セクションまでスクロールし、次のように X-Apigee-fault-code と X-Apigee-fault-source の値を特定します。

  13. X-Apigee-fault-code と X-Apigee-fault-source の値はそれぞれ protocol.http.EmptyPath と target になります。これは、 バックエンド サーバーの 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.EmptyPathを含む500エラーがあるかどうか、または500で失敗しているリクエストがまだあるかどうかを検索します。
  4. X-Apigee-fault-code が値 protocol.http.EmptyPath に一致する 500 エラーが見つかった場合は、X-Apigee-fault-source の値を特定します。

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

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

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

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

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

診断

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

  4. フロー変数 target.url に空のパスが含まれているかどうかと、その値のソースを次のいずれかの手順で特定します。

    トレース

    Trace ツールを使用する

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

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

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

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

    ログ

    ログサーバーでログを使用する

    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
    • パス: 空

    パスが空であるため、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);

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

    実際のリクエストまたはトレースにアクセスできる場合は、渡された実際の値 を 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
    • パス: 空

    サンプル 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
    • パス: 空

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

解決策

仕様 RFC 3986、セクション 2: Syntax Components に準拠しています。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);

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

    リクエスト例:

    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: Syntax Components
RFC 3986、セクション 3.3: Path

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

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

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

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

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

参照

フロー変数 - ターゲット