nykergoto’s blog

機械学習とpythonをメインに

Vercel で 502 OPTIMIZED_EXTERNAL_IMAGE_REQUEST_UNAUTHORIZED Error に遭遇する。

前提

  • Next.js を利用したアプリケーションを vercel へデプロイして利用している。
  • 一部 item 詳細ページでは SSG を使っていて、一覧ページでは逐次別でホスティングしている API へリクエストを送る。
  • 取得した item ごとに画像が紐付いていて、画像は cloudfront でホスティングされている。
  • 画像の表示には next/image Image を利用している。したがって next.js の API 機能によって最適化がされている状態。

発生したこと

  • ローカル環境での dev では問題なく画像が表示されていて、そのまま vercel 上へ build & depoly した。deploy までは特にエラー無く実行できた。
  • 変更へ紐づくURLを preview でみてみると、殆どの画像が 502 OPTIMIZED_EXTERNAL_IMAGE_REQUEST_UNAUTHORIZED エラーになり表示できていないことがわかった。

対応した (が上手く行かなかった) こと

  • そもそも設定が間違っている可能性を考えてローカル環境で vercel がやっている(であろう)ことと同じ構成を試す。
    • 具体的には同じ env を設定したのち npm run build & npm run start をし localhost に立ったサーバにブラウザでアクセスした。すると、問題なく画像は表示された。
    • _next/iamges/ へのリクエストも問題なく通っている。
    • このときの画像ドメインはさきほどエラーがあったドメインと同じもの。
  • Web上で同じエラーメッセージで検索しても何も出てこない。vercel 公式のエラー一覧 https://vercel.com/docs/errors にもこのエラーコードがない (どういうこと?)

ここまでで困って twitter でつぶやいていたところ vercel の @jrsyo さんに tweet を見つけていただき DM で対応してもらいました。

(やさC)

結論何が問題だったか

画像の cloudfront にアクセス制限がかかっており local = ja のみアクセス可能になっていたことが問題でした。terraform の設定的に言うと、以下のような記載をしていました。

  restrictions {
    # 日本以外は許可しない設定
    geo_restriction {
      restriction_type = "whitelist"
      locations        = ["JP"]
    }

ローカル環境は日本なので、問題なくアクセスできます。ただし vercel のエンドポイントは日本以外のどこかに立っています (確かアメリカのハズ)。

したがって、ある画像@cloudfront をフロントエンドから vercel の画像最適化用のエンドポイント _next/image へリクエストすると, vercel → cloudfront へリクエストが飛びますが, vercel は日本にはないためアクセスが遮断され, vercel → cloudfront のリクエストが 403 error になり、結果フロントエンドには 502 OPTIMIZED_EXTERNAL_IMAGE_REQUEST_UNAUTHORIZED が帰る、ということでした。

日本から利用することをメインに想定するアプリを作ることが多く上記設定をテンプレートに入れていたのですが、それを忘れていたことが原因なのですが cloudfront を疑うパターンが少なかったのでハマってしまいました。

余談

vercel の管理画面やエラー詳細ではそのような表示は見つけられなかった (ゆえに cloudfront の設定を疑っていなかった…) ので、エラーの細かいものを見る画面はないですかー? と @jrsyo さんに聞いたところ、今現在は提供されていないとのことでした。エラーの中身が見えるようになると嬉しいな🦈( ‘-’ 🦈)。vercel の追加開発に期待です。