Azure AI Document Intelligenceで「Long running operation failed」が出たときの原因と対処法

Azure AI Document Intelligence(旧 Form Recognizer)を使っていると、前日まで普通に動いていたのに、ある日突然「Long running operation failed.」だけを残して失敗することがあります。本記事では、2025 年 7 月に実際に発生した LLM05062025 モデルの事例を題材に、このエラーの正体・よくある原因・具体的な切り分け手順・運用ベストプラクティスを、Azure ポータルや AI Foundry ポータルの画面操作レベルまで落とし込んで解説します。

目次

Azure AI Document Intelligence の「Long running operation failed」とは?

まず押さえておきたいのは、「Long running operation failed.」という文字列自体はDocument Intelligence 固有のエラーコードではなく、Azure の長時間実行(LRO: Long-Running Operation)をラップしている SDK 側の汎用メッセージである、という点です。 実際の原因は、裏側で呼び出されている REST API のレスポンス JSON に含まれる error.code や error.innererror.code に書かれています。

Azure AI Document Intelligence の多くの処理(begin_analyze_document など)は、最初のリクエストで処理を開始し、その後ポーリングしながら完了を待つ LRO として実装されています。 この途中経過のどこかで 4xx / 5xx 系のエラーや内部タイムアウトが発生すると、SDK が「Long running operation failed.」とまとめて報告し、アプリ側からは「何が悪いのか分からない」状態に見えてしまいます。

今回の事例:モデル LLM05062025 で突然失敗するケース

ユーザーから寄せられた具体的な相談内容を、時系列で整理すると次のようになります。

日時出来事
2025-06-05AI Foundry ポータルでモデル LLM05062025 を作成
2025-07-03同モデルで、3 ページの PDF を正常に解析(成功)
2025-07-04 夜同じ 3 ページ PDF を同じエンドポイント URL/キー/リソースで処理したところ、 “Long running operation failed.” エラーで失敗。
さらに、同じリソース上の別モデルでもまったく同じエラーが発生。

ポイントは、アプリのコードや入力 PDF は変えていないのに、同じリソース上の他モデルでも一斉に失敗するという点です。 これは、モデル定義やアプリロジックよりも、サービス側(リージョン/リソース/クォータ/ネットワーク)に起因する可能性が高いシグナルになります。

Long-running operation の仕組みと、見るべきログ

LRO の基本的な流れ

Document Intelligence の代表的な LRO の流れを、REST ベースでざっくり整理しておきます。

  1. POST /documentintelligence/documentModels/{modelId}:analyze に PDF や画像を送信
  2. サーバーは 202 Accepted を返し、レスポンスヘッダ operation-location にステータス取得用 URL を返す
  3. クライアントはその URL に対して GET を繰り返し呼び、status が succeeded または failed になるまでポーリング
  4. status: "failed" のとき、レスポンス JSON の error オブジェクトに詳細が入る

この status: "failed" を検知すると、各言語の SDK は LRO を例外として投げ、その際の例外メッセージが 「Long running operation failed.」 となることが多い、という構造です。

JSON レスポンスで必ず確認したいフィールド

Document Intelligence のエラーは、次のような構造で返ってきます。

  • status … notStarted / running / succeeded / failed / canceled
  • error.code … InvalidRequest / InternalServerError / Forbidden / ServiceUnavailable など
  • error.innererror.code … InvalidContent, InvalidSasToken, NotSupportedApiVersion などより具体的な原因
  • error.details[] … 複数のページやファイルで個別に起きたエラーの一覧(長い PDF やバッチ処理で重要)

「Long running operation failed.」とだけ表示されてしまう場合でも、バックエンドの JSON レスポンスには必ずヒントがあります。 まずは SDK の例外から生の JSON を拾う、もしくは Azure Monitor の診断ログから同じリクエストのレスポンスボディを確認する、というのが第一歩になります。

原因候補の全体像:よくある落とし穴マップ

実際のサポート事例や Microsoft Q&A のやり取りを踏まえると、「Long running operation failed」が出るときの主な原因は次のように整理できます。

カテゴリ典型的な症状最初に疑うポイント
一時的なサービス障害/リージョン障害前日まで同じコード・同じ PDF で成功していたのに突然失敗する。複数モデルで同時に失敗。Azure ステータスページ、同リージョンの他リソース/他サブスクリプションでの再現有無
API バージョンとモデル/SDK の不整合一部モデルだけ失敗、NotSupportedApiVersion やバージョン関連のエラー。api-version パラメータ、SDK バージョン、コンテナのタグ(バージョン)
クォータ超過/スロットリング負荷を上げた途端に失敗し始める。ときどき成功する。429 / 503 が混ざる。Document Intelligence の TPS(秒間トランザクション数)と同時実行上限、バックオフ実装の有無
内部エラー(500 系)InternalServerError や ServiceUnavailable が返る。再試行で回復することもある。リージョンの障害情報、既知のバグ、仕様変更、サポートチケットの有無
リソースの遷移中状態リソース作成直後や設定変更直後にだけ失敗。時間を置くと直る。ポータル上の状態が「Succeeded」になっているか、更新中になっていないか
ネットワーク/ストレージ/SASストレージの SAS 有効期限切れ、VNet/Firewall 越しのアクセス失敗。SAS の有効期限・権限、Private Endpoint・ファイアウォール設定、ContentSourceNotAccessible 系エラー
入力ファイルの問題特定の PDF だけ失敗する。InvalidContent、InvalidContentDimensions など。ファイル形式・サイズ・ページ数・解像度、破損の有無、他ツールでの開閉可否

今回のケースでは、別モデルでも同じエラーが同一リソースで同時期に発生しているため、特に「一時的なサービス障害」「クォータ/スロットリング」「リソースの遷移中状態」「ネットワーク/ストレージ」の線を優先して疑うべき状況です。

優先度順:実際の調査ステップ

1. Azure ステータスとメトリクスの確認

まずは「自分だけの問題なのか」「リージョン全体の問題なのか」を切り分けます。

  • Azure ステータスページの確認 Azure のサービス正常性ページで、Document Intelligence を含む AI サービスに障害やレイテンシのアラートが出ていないか確認します。過去にも特定リージョンで Document Intelligence のレスポンスが極端に遅くなったり、処理が完了しない事例が報告されています。
  • Azure ポータルのメトリクス Document Intelligence リソースの「インサイト」から Request latency / Request count / Throttled requests などのメトリクスを確認し、エラーが発生した時間帯にスパイクやスロットリングがないかを確認します。Microsoft は公式ドキュメントで、レイテンシ問題のトラブルシュートとアラート設定方法を案内しています。

この段階で「その時間帯だけ全体のレイテンシが跳ね上がっている」「スロットリング(429)のメトリクスが急増している」などが見つかれば、アプリの変更ではなくサービスや負荷が原因である可能性が高くなります。

2. API バージョンとモデル/SDK の整合性チェック

Document Intelligence は現在、主に次の REST API バージョンが使われています。

世代REST API バージョン代表的な用途
v3.12023-07-31従来の Layout / Read / prebuilt-* モデル(多くの既存コードがこれ)
v4.02024-11-30最新の REST API/SDK。追加機能(Batch API、検索可能 PDF、クエリフィールド等)が利用可能

各言語の SDK には「対応している API バージョン」があり、ドキュメントにも対応表が記載されています。 さらに一部の SDK では api_version を明示的に上書きすることもできますが、Microsoft は「対応外のバージョンを指定するとサポートされない動作になる可能性がある」と注意書きをしています。

コンテナ版や一部のシナリオでは、モデルが前提としている API バージョンと、呼び出し側の api-version がズレているとエラーになることがあり、Q&A でも prebuilt-read:analyze を使う場合には api-version=2023-07-31 を合わせるよう案内されていました。

そのため、次の点を必ず確認してください。

  • AI Foundry から表示される「呼び出しサンプル」に記載の api-version と、実際のアプリから投げている API バージョンが一致しているか
  • コンテナを使っている場合は、コンテナのタグ(例:3.1、4.0)が想定と合っているか
  • SDK で api_version を明示指定しているなら、その値がサービス側でサポートされていることをドキュメントで確認する

3. JSON レスポンス/診断ログで「本当のエラーコード」を確認

「Long running operation failed.」に惑わされず、必ず JSON の error.code と error.innererror.code を特定しましょう。

確認方法の例:

  • C# や Python の SDK なら、例外オブジェクトの中にある response や error をログに出力する
  • REST 直接呼び出しなら、GET {operation-location} で返ってきた JSON をそのまま保存する
  • Azure Monitor の診断設定で「リクエスト/レスポンス」を Log Analytics に送るようにしておき、該当時間帯のログを検索する

ここで例えば InternalServerError や ServiceUnavailable であればサービス側/リージョンの問題、NotSupportedApiVersion であれば API バージョン不整合、InvalidSasToken や ContentSourceNotAccessible であればストレージや SAS の問題といった具合に、次に取るべきアクションがほぼ決まります。

4. クォータ/スロットリングをチェック

Document Intelligence には、リソースごとにトランザクション数や同時実行数の上限が設定されています。現在のドキュメントでは、標準プランの分析リクエスト(POST)はデフォルトでおよそ 15 TPS 程度が上限とされており、これを超えると 429(TooManyRequests)でスロットリングされます。

チェックのポイント:

  • エラー発生時刻に、アプリ側で並列処理数やバッチサイズを増やしていないか
  • Log Analytics で 429 / 503 の割合が急に増えていないか
  • ポータルの「サービス クォータと制限」画面で、秒間トランザクション数や同時実行数に余裕があるか

もしクォータが上限に張り付いているようであれば、指数バックオフ付きの再試行と、負荷の緩やかな増加(スパイクを避ける)を実装したうえで、必要に応じてクォータ増加申請(サポートリクエスト)を行うのが定石です。

5. リソース状態・ネットワーク・SAS の確認

ここまででサービス全体の障害やクォータの問題がなさそうな場合、次はリソースと入力データ周りを確認します。

  • リソース状態 AI Foundry や Azure ポータルで、Document Intelligence リソースの状態が 「Succeeded」 になっているかを確認します。Q&A の回答でも、更新/再構成中の一時的な不整合がエラーの原因になりうると案内されています。
  • SAS トークンの有効期限とネットワーク FAQ では、ストレージの SAS の既定有効期限は 48 時間程度であり、期限切れや VNet/Firewall によるブロックがあると ContentSourceNotAccessible や InvalidSasToken といったエラーが返ると説明されています。 同じファイルをブラウザで直接開けるか、IP 制限や Private Endpoint の設定が変わっていないかも確認しましょう。

6. 別リージョン/別リソースでのクロステスト

原因が特定できない場合は、「データ依存」か「環境依存」かを切り分けるためにクロステストを行います。

  • 同じ 3 ページ PDF を、近い別リージョン(例:East US → West US)に作成した Document Intelligence リソースで解析してみる
  • 同じリージョン内で、別のサブスクリプションや別のリソースを作成して試す
  • 公式サンプルの PDF(請求書など)を使い、同条件で成功/失敗の差を確認する

「別リージョンだと常に成功する/別リソースなら成功する」といった結果が得られれば、問題がリージョンや特定リソースに閉じていると分かるため、サポートにエスカレーションする際の材料にもなります。

HTTP ステータス/エラーコード別の見立てと対処

実務で便利なように、代表的な HTTP ステータス+エラーコードと、最初に疑うべきポイントを一覧でまとめます。

HTTP ステータス / エラーコードよくある原因推奨アクション
500 / InternalServerErrorサービス内部の一時的な障害、まれにバグやリージョン障害指数バックオフ付きで数回再試行し、それでも再現するなら Azure ステータスとサポートに問い合わせ
503 / ServiceUnavailable一時的な負荷増・メンテナンス・スロットリング再試行と負荷調整(スパイクを避ける)、クォータと自動スケーリングの設定を見直す
429 / TooManyRequestsTPS 上限や同時実行上限に到達しているバックオフとキューイングを導入し、必要であればクォータ増加を申請
400 / InvalidRequestパラメータやファイルの問題(フォーマット、サイズ、ページ数など)innererror.code を確認し、InvalidContent、InvalidContentDimensions などの具体的なメッセージに従って修正
400 / NotSupportedApiVersion使用している API バージョンがその操作・モデルでサポートされていないドキュメントの対応表を確認し、api-version を正しい値に変更する
401 / 403 / AuthorizationFailed, Forbiddenキー無効、RBAC 設定不備、IP 制限、Outbound アクセス制限などキー再発行、ロール割り当て確認、IP 許可リストと Private Link 設定を確認
400 / ContentSourceNotAccessible, InvalidSasTokenSAS 期限切れ、権限不足、VNet/Firewall によるブロック新しい SAS を作成し、有効期限を十分に長く設定。VNet/Firewall の設定も見直す

最小構成での再現・切り分け手順

複雑なアプリケーション全体を追いかけるよりも、まずは「最小構成で同じ PDF が解析できるか」を試すほうが速く原因にたどり着けます。

ステップ 1: 公式サンプル+REST で試す

  1. Document Intelligence の公式サンプルリポジトリから、サンプルの請求書 PDF などを取得する
  2. AI Foundry ポータルで、対象モデル(例:prebuilt-layout やカスタムモデル)の「コードサンプル」を開く
  3. 記載されている endpoint と api-key、api-version をそのまま使って Postman などで REST 呼び出しする
  4. これで成功するか/同じように「Long running operation failed」になるかを確認

ここで成功する場合、アプリ側の実装(ヘッダや api-version、SAS 生成方法など)に何らかの差異がある可能性が高いです。一方、ここでも同じように失敗する場合は、リソースやリージョン、クォータなど環境側の要因が疑われます。

ステップ 2: 同一ファイルで別リージョンを試す

  1. 元と同じ設定で、別リージョン(例:Japan East → Japan West)に Document Intelligence リソースを新規作成
  2. 同一の 3 ページ PDF を、その新リソース経由で解析
  3. 成功する/失敗するケースを比較し、リージョン依存かどうかを判断

ステップ 3: 別ファイルで同リージョンを試す

  1. 問題が発生した 3 ページ PDF とは別の、シンプルな PDF(テキストのみなど)を同じモデルに渡す
  2. シンプルな PDF では成功するが、特定の PDF だけ失敗するのであれば、ファイル依存の問題(サイズ、フォント、破損など)の可能性が高い

指数バックオフ付きポーリング実装例(Python)

Document Intelligence の Python SDK(azure-ai-documentintelligence)では、begin_analyze_document が返すポーラーに対して result() を呼ぶだけで内部ポーリングが行われますが、429 / 500 / 503 など一時的なエラーに対してはアプリ側の再試行戦略も重要です。

イメージしやすいように、簡略化したコード例を示します(考え方の参考例です)。


from azure.core.exceptions import HttpResponseError
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient

endpoint = "https://<your-resource-name>.cognitiveservices.azure.com/"
key = "<your-key>"

client = DocumentIntelligenceClient(endpoint, AzureKeyCredential(key))

def analyze_with_retry(model_id: str, document_path: str):
    max_retries = 5
    base_delay = 2  # seconds
    for attempt in range(max_retries):
        try:
            with open(document_path, "rb") as f:
                poller = client.begin_analyze_document(model_id, body=f)
                result = poller.result()  # LRO 完了まで待機
                return result
        except HttpResponseError as ex:
            status = ex.status_code
            # 一時的エラーだけ再試行
            if status in (429, 500, 503) and attempt < max_retries - 1:
                delay = min(base_delay * (2 ** attempt), 60)  # 最大 60 秒まで
                print(f"Transient error {status}. retry after {delay}s...")
                time.sleep(delay)
                continue

            # それ以外のエラーは即座に詳細をログ出力して再送しない
            print("Request failed with error:", ex)
            if hasattr(ex, "error"):
                print("Error code:", getattr(ex.error, "code", None))
            raise

ポイントは、「429 / 500 / 503 など一時的なものだけを指数バックオフで再試行し、それ以外はすぐに詳細ログを見て原因を直す」という方針を明確にしておくことです。

今回のケースに当てはめた見立て

ここまでの整理を、今回の LLM05062025 モデルの事例に当てはめると、次のように考えるのが自然です。

  • 2025-07-03 時点では同じ PDF が問題なく解析できている
  • 2025-07-04 夜、同じ PDF・同じリソース・同じコードで「Long running operation failed」
  • 同一リソース上の別モデルでも同時期に同じエラー

この状況からは、次のような優先度で切り分けるのが合理的です。

  1. Azure ステータスと Document Intelligence のメトリクス確認 同時間帯にリージョン全体のレイテンシやエラー率が悪化していないかを確認します。
  2. JSON レスポンスの error.code と innererror.code の取得 まずはエラーの「姓と名」を知ることが最優先です(例:InternalServerError+InvalidContent なのか、NotSupportedApiVersion なのか)。
  3. クォータ/スロットリング 夜間バッチなどで負荷が上がっている場合、クォータ上限到達からの 429/503 → LRO 失敗というシナリオはよくあります。
  4. リソース状態とネットワーク/SAS リソースが Updating 等になっていないか、SAS の期限・権限や VNet/Firewall 設定に変更が入っていないかを確認します。
  5. API バージョンの整合性確認 もし直前に SDK のアップデートやコンテナのバージョン変更があった場合は、api-version との組み合わせを見直します。

特に、今回のように「別モデルでも同じリソースで一斉に失敗」というパターンは、クォータ・リージョン障害・リソースの遷移中状態・ネットワークなど「環境側」の要因を強く示唆します。アプリ固有のバグやモデル品質の問題であれば、特定のモデルや特定ドキュメントだけが失敗することが多いからです。

運用でハマらないためのベストプラクティス

最後に、「Long running operation failed」を本番運用で最小限に抑えるためのベストプラクティスをまとめます。

  • エラー JSON を常に記録する 例外メッセージだけではなく、status / error.code / innererror.code / details を Log Analytics や独自ログに必ず残す。
  • 429 / 500 / 503 に対する指数バックオフ LRO の再試行戦略を明文化し、一時的な障害に強い設計にする。
  • クォータ監視とアラート Request latency / Throttled requests などにアラートを設定し、しきい値を超えたら自動で通知されるようにする。
  • API バージョンと SDK の固定(ピン止め) 検証済みの組み合わせを CI/CD で固定し、サービス側の新バージョンに追従するときはステージング環境で十分に試してから本番へ。
  • SAS とネットワークのライフサイクル管理 SAS 有効期限がジョブの実行時間より十分長いことを確認し、ネットワーク側の変更(Firewall ルール等)は Document Intelligence リソースへの影響を必ずチェックする。
  • 別リージョン/別リソースを使った DR 設計 重要なワークロードでは、別リージョンの Document Intelligence リソースを用意しておき、片側に障害が起きた場合に切り替えられるようにしておく。

まとめ

「Long running operation failed」はあくまで「長時間実行ジョブが失敗した」という結果だけを表すラッパーメッセージであり、真の原因は常にその背後にある JSON エラーや環境の状態に隠れています。

今回のように、同一リソース上の複数モデルで同時にエラーが出る場合は、アプリやモデルそのものよりも、リージョン/リソース/クォータ/ネットワークといった環境側の要因を優先して疑うのが効率的です。 本記事で紹介したチェックリストと切り分け手順、そして指数バックオフやクォータ監視といった運用の工夫を取り入れることで、Azure AI Document Intelligence における「Long running operation failed」トラブルを、より短時間で、再発しづらい形で解決できるはずです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次