言語を切り替える
テーマを切り替える

Cloudflare Pagesビルド失敗?8つのよくある問題と解決策でデバッグ時間を半日短縮

深夜2時、Cloudflare Pagesのビルドログに表示される赤い「Failed」の文字を呆然と見つめる……。今夜でもう5回目です。明日の朝、クライアントにデモを見せなければならないのに、この忌々しいデプロイエラーのせいで立ち往生しています。
「ローカルでは動いているのに、Pagesにプッシュした途端に爆発する」、そんな経験はありませんか? 500行にも及ぶログ、画面を埋め尽くす npm ERR!、どこから手を付ければいいのか分からない絶望感。ネットで見つけた解決策を試しても効果がなく、むしろ悪化することさえあります。そして疑心暗鬼になります。「私のコードが悪いのか? それともCloudflareの問題か?」

正直なところ、私も最初はそうでした。何度も失敗し、数百ものコミュニティ投稿を読んで、ようやくパターンが見えてきました。実は、Pagesのビルド失敗の9割は、**「環境の差異」「依存関係」「バージョン互換性」**の3つに集約されます。

この記事では、Cloudflare Pagesのビルド環境を体系的に理解し、8つの最も一般的な失敗パターン(実際のエラーログと完全な解決手順付き)と、再発を防ぐ設定を紹介します。これを読めば、もう闇雲にデバッグする必要はなくなります。

第一部:Cloudflare Pagesのビルド環境を理解する

Pages ビルド環境の特殊性

まず理解すべきは、Pagesのビルド環境はあなたのローカル環境とは「別物」だということです。エラーの原因はコードではなく、環境の違いにあることが多いのです。

デフォルト設定の現状

Ubuntu 22
OS
Build System V2
18.17.1
Nodeバージョン
デフォルトは古め
20分
タイムアウト
強制終了のハードリミット
10MB
Workerサイズ上限
Functionsバンドル制限
  • OS: Ubuntu(Build System V2はUbuntu 22)
  • Nodeバージョン: 18.17.1(意外と古いです)
  • パッケージマネージャー: デフォルトで npm clean-install (npm ci) を使用
  • タイムアウト: 20分で強制終了
  • Workerサイズ: 10MBまで

なぜNodeが古いのか? 安定性のためですが、これが新しいライブラリ(Node >= 18.18.0 や >= 20.0.0 を要求するもの)との衝突を生みます。

ローカル環境との3つの決定的な違い

  1. 大文字・小文字の区別(Case Sensitivity): WindowsやMacでは import Header from './header' と書いても、ファイル名が Header.js であれば動きます。しかしLinuxでは厳密に区別されるため、ビルドに失敗します。これが最も見落としがちな罠です。
  2. ネットワーク環境: ローカルではプロキシやミラーサーバを使っているかもしれませんが、Pagesはnpm公式レジストリに直接接続するため、タイムアウトすることがあります。
  3. ビルドコマンド: Cloudflareは build command の前に自動的に npm clean-install --progress=false を実行します。これは npm install よりも厳格で、package-lock.jsonpackage.json に矛盾があると即座にエラーになります。

問題を素早く特定する方法

ステップ1:ビルドログを解読する
何百行もあるログに圧倒されないでください。見るべき場所は決まっています。

# "ERR!" または "ERROR" の最後の出現箇所を探す
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve

# Vite/Webpackのエラー
[vite]: Rollup failed to resolve import

# Git関連のエラー
fatal: unable to access repository

コツは、ブラウザの検索機能で「ERR!」(感嘆符込み)を検索し、そこから3〜5行上を見ることです。そこに真因があります。

ステップ2:Deployment IDを保存する
失敗するたびに、ブラウザのURLバーにユニークなIDが表示されます。
https://dash.cloudflare.com/xxx/pages/view/your-project/a398d794-7322-4c97-96d9-40b5140a8d9b
末尾のUUIDがそれです。サポートに問い合わせたり、コミュニティで質問する際に必須となります。

ステップ3:ローカルでの再現
Dockerを使って、ローカルでLinux環境をシミュレートするのが確実です。

# 方法1: DockerでUbuntu 22環境を再現
docker run -it ubuntu:22.04 bash
# 方法2: npm ci を実行(Pagesと同じコマンド)
npm ci
# 方法3: Nodeバージョンを合わせる(nvm使用)
nvm use 18.17.1

ローカルで npm ci が失敗するなら、依存関係の設定ミスです。Node 18.17.1で失敗するなら、バージョンの互換性問題です。

第二部:8つのよくある失敗パターンと解決策

問題1:依存関係のインストール失敗(npm install エラー)

典型的なエラー

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! Fix the upstream dependency conflict, or retry this command
npm ERR! with --force or --legacy-peer-deps

または

npm ERR! code ERR_SOCKET_TIMEOUT
npm ERR! network Socket timeout

原因
Cloudflareが使用する npm ci は、peer dependencyの競合を自動解決しません。また、package-lock.json が古かったり壊れていたりすると失敗します。

解決策
案1:デフォルトインストールをスキップし、コマンドをカスタマイズ(推奨)
Pagesの設定で環境変数を追加します:
SKIP_DEPENDENCY_INSTALL=true
そして、Build commandを以下のように変更します:
npm install --legacy-peer-deps && npm run build
これでCloudflareの厳格なチェックを回避し、自分で依存関係を解決できます。

案2:package-lock.jsonの再生成

rm package-lock.json
npm install
git add package-lock.json
git commit -m "fix: regenerate package-lock.json"
git push

案3:GitHub Actionsの使用
上記でもダメな場合は、GitHub Actionsでビルドし、cloudflare/pages-action でデプロイする方法に切り替えましょう。環境を完全に制御できます。

問題2:Nodeバージョンの非互換

典型的なエラー

ERR_PNPM_UNSUPPORTED_ENGINE Unsupported environment
This package requires Node.js version ^18.18.0 or >=20.0.0
# または
The engine "node" is incompatible with this module.
Expected version ">=18.18.0". Got "18.17.1"

解決策
案1:環境変数の設定(最重要)
Pagesの Settings > Environment variables に以下を追加:

  • 変数名: NODE_VERSION
  • 値: 20.11.0 (LTS推奨)

案2:.node-version ファイル
プロジェクトルートに .node-version ファイルを作成し、バージョン番号(例:20.11.0)を記述してコミットします。

問題3:ビルドタイムアウト(20分超過)

症状
明確なエラーなく、ちょうど20分でビルドが止まり、「Build exceeded maximum time of 20 minutes」と表示される。

解決策
案1:ビルドキャッシュのクリア
Settings > Builds & deployments > Clear build cache を実行して再ビルド。キャッシュの整合性が取れていない場合があります。

案2:依存関係の分析
@next/bundle-analyzer などを使い、巨大なパッケージ(例:moment.js)が含まれていないか確認し、軽量な代替品(day.jsなど)に置き換えます。

案3:pnpmの使用
npmよりも高速な pnpm を使用設定にします。Build commandを pnpm install && pnpm run build に変更します。

問題4:モジュールが見つからない(Module not found)

典型的なエラー

Module not found: Error: Can't resolve './App' in '/opt/buildhome/repo/src'
Did you mean 'App.js'?

原因
ファイル名の大文字・小文字の不一致です(例:ファイルは App.js なのに import ... from './app' としている)。

解決策
すべての import パスを確認し、ファイル名の大文字・小文字と完全に一致させます。vite.config.js でエイリアス(@ など)を設定しておくとミスを防げます。
また、フォルダ名の大文字小文字を変更した場合、Gitが変更を検知しないことがあります。一度リネームしてコミットし、戻してコミットするという「おまじない」が必要な場合もあります。

問題5:環境変数の設定ミス

症状
コード内で process.env.API_KEYundefined になる。

原因と解決策

  1. ビルド時 vs ランタイム:静的サイト(SSG)の場合、環境変数はビルド時に埋め込む必要があります。
  2. プレフィックス:フレームワークの規則に従ってください。
    • Vite: VITE_
    • Next.js: NEXT_PUBLIC_
  3. 設定漏れ: PagesのSettings > Environment variables で、ProductionPreview の両方に設定されているか、Build オプションがチェックされているか確認してください。

問題6:Git連携エラー

症状
“This repository is already in use by another Pages project” と表示される、またはPushしてもビルドが始まらない。

解決策

  • 権限確認: そのリポジトリに対して Maintainer 以上の権限が必要です。
  • 再連携: GitHub設定 > Applications > Cloudflare Pages から一度Uninstallし、Cloudflare側で再接続します。
  • 重複利用: 別のCloudflareアカウントで同じリポジトリを連携していないか確認してください。

問題7:Functions(Worker)のデプロイ失敗

症状
Build failed: Functions bundle size exceeding limit

解決策

  • サイズ超過: Workerは圧縮後10MBまでです。不要なライブラリを削るか、Astro/SvelteKitの場合はアダプターの設定で mode: 'directory' などに変更し、不要なファイルを含めないようにします。
  • Node.js APIの使用: WorkersはV8環境であり、Node.jsの fschild_process は使えません。これらを使用しているコードを除去するか、ビルドプロセスで処理するように変更してください。

問題8:キャッシュとカスタムドメインの問題

症状
デプロイ成功と表示されるが、サイトの内容が更新されない。404エラーが出る。

解決策

  • ページルールの競合: Cloudflareの Zone 設定で “Cache Everything” のPage Ruleを設定している場合、Pagesの更新が即座に反映されません。ルールを削除するか、Pages用ドメインを除外してください。
  • DNS設定: カスタムドメインのDNSレコードを「DNS Only(灰色の雲)」に変更して、Cloudflareのプロキシをバイパスすることで解決するか確認してください(通常はプロキシ(オレンジの雲)でも問題ありません)。
  • パージ: キャッシュをパージ(Clear Cache)してみてください。

第三部:再発を防ぐベストプラクティス

1. Nodeバージョンを明示する
プロジェクトルートに .node-version を置き、環境変数 NODE_VERSION も設定する二重化を行いましょう。

2. ブランチごとにコマンドを分ける
CF_PAGES_BRANCH 環境変数を使って、main ブランチは本番ビルド、それ以外はプレビュービルド(高速化のためソースマップなし等)といった分岐を package.json のスクリプトで制御できます。

3. ローカルデバッグ環境の整備
Dockerを使った検証環境を作っておくと、謎のエラーに遭遇した際に役立ちます。

# デバッグ用Dockerfile
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y nodejs npm
# ...以下略

結論

Pagesのビルド失敗は、90%が環境差異依存関係設定ミスのいずれかです。
むやみに設定をいじる前に、まずはログを読み、Deployment IDを控え、冷静に原因を分類してください。この記事のチェックリストを使えば、トラブルシューティングの時間は劇的に短縮されるはずです。
あの緑色の ”✓ Success” 、“Deployed” の文字を見た時の安堵感を、あなたもすぐに味わえるようになります。

Cloudflare Pagesビルド失敗トラブルシューティング

ビルドエラーの原因特定から解決までの完全フロー

⏱️ Estimated time: 15 min

  1. 1

    Step1: エラーログの特定

    ビルドログから "ERR!" や "ERROR" を検索し、その直前の行を読んで真のエラー原因(依存関係、モジュール解決、権限など)を特定する。
  2. 2

    Step2: 環境変数の設定

    Nodeバージョンの不一致が疑われる場合、Environment variablesに "NODE_VERSION: 20.11.0" を追加して再ビルド。
  3. 3

    Step3: 依存関係のクリーンアップ

    npm install エラーの場合、Build commandを "npm install --legacy-peer-deps && npm run build" に変更するか、package-lock.json を再生成する。
  4. 4

    Step4: キャッシュクリア

    Settings > Builds & deployments > Clear build cache を実行し、古いキャッシュによる不整合を解消する。

FAQ

変更をPushしてもビルドが始まりません。
Cloudflare PagesとGitHub/GitLabの連携が切れている可能性があります。GitHubのSettings > ApplicationsからCloudflare Pagesを一度アンインストールし、Cloudflareダッシュボードから再接続してみてください。また、コミットメッセージに絵文字や特殊文字が含まれていると稀にトリガーされないことがあります。
「Module not found」エラーが消えません。
ファイル名の大文字・小文字がコード内のimport文と完全に一致しているか確認してください。Gitはデフォルトでファイル名の大文字小文字の変更を検知しないため、"git mv file.js file_temp.js" してから "git mv file_temp.js File.js" のようにリネームしてコミットする必要があります。
デプロイしたのに404エラーになります。
ビルドの出力ディレクトリ(Build output directory)の設定が間違っている可能性があります。Viteなら"dist"、Create React Appなら"build"、Next.js(静的エクスポート)なら"out"になっているか確認してください。また、SPAの場合はルートディレクトリに redirect ルール(_redirectsファイル)が必要な場合があります。

5 min read · 公開日: 2025年12月1日 · 更新日: 2026年1月22日

コメント

GitHubアカウントでログインしてコメントできます

関連記事