15 Error Deploy Paling Umum dan Solusinya
Pesan error yang paling sering muncul saat deploy ke Netlify, Vercel, Cloudflare, dan GitHub Pages — penyebab sebenarnya dan cara memperbaikinya.
Deploy gagal itu hampir selalu satu dari belasan masalah yang sama, berulang. Halaman ini mengumpulkannya — diurutkan dari yang paling sering muncul — lengkap dengan pesan error aslinya supaya bisa dicari cepat di halaman ini.
Untuk tiap error: pesan yang muncul, apa yang sebenarnya terjadi, dan cara memperbaikinya.
1. Build berhasil di laptop, gagal di server
Error: Cannot find module './components/Header'
Module not found: Can't resolve './utils/Format'
Penyebabnya hampir pasti huruf besar-kecil. macOS dan Windows memperlakukan Header.jsx dan header.jsx sebagai berkas yang sama. Server build memakai Linux, yang membedakannya. Jadi impor yang salah kapital tetap jalan di laptopmu dan langsung mati di server.
Periksa nama berkas aslinya, lalu samakan persis dengan yang kamu tulis di import. Kalau kamu sudah terlanjur mengubah kapitalisasi, Git di macOS dan Windows kadang tidak mencatatnya. Paksa dengan:
git mv --force header.jsx Header.jsx
git commit -m "perbaiki kapitalisasi nama berkas"
2. Halaman 404 setelah refresh
Aplikasi jalan normal, navigasi antar halaman lancar. Tapi begitu kamu refresh di /tentang, muncul 404.
Ini bukan bug aplikasimu. Router seperti React Router atau Vue Router bekerja di sisi browser. Saat kamu refresh, browser meminta /tentang ke server — dan server mencari berkas bernama tentang yang memang tidak ada. Solusinya: suruh server mengembalikan index.html untuk semua rute, biar router yang menangani sisanya.
Netlify — bikin public/_redirects:
/* /index.html 200
Vercel — bikin vercel.json di root:
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
Cloudflare Workers — di wrangler.jsonc:
"assets": {
"directory": "./dist",
"not_found_handling": "single-page-application"
}
GitHub Pages tidak punya aturan rewrite. Akalinya dengan menyalin index.html jadi 404.html saat build — GitHub akan menyajikannya untuk rute yang tidak ditemukan.
3. Versi Node berbeda
error: This package requires Node >=20.0.0
SyntaxError: Unexpected token '??='
Platform memakai versi Node default mereka, yang belum tentu sama dengan versimu. Kunci versinya secara eksplisit.
Cara yang jalan di hampir semua platform — bikin berkas .nvmrc berisi satu baris:
20
Atau lewat package.json:
"engines": { "node": ">=20" }
Netlify juga membaca environment variable NODE_VERSION, dan Vercel punya pilihan versi Node di Project Settings.
4. npm ci gagal karena lockfile
npm ci can only install packages when your package.json and
package-lock.json are in sync
Kamu mengubah package.json tanpa memperbarui lockfile-nya. npm ci — yang dipakai hampir semua platform — menolak menebak.
npm install
git add package-lock.json
git commit -m "sinkronkan lockfile"
Pastikan juga package-lock.json tidak masuk .gitignore. Lockfile memang seharusnya ikut ter-commit.
5. Environment variable tidak terbaca
Berkas .env.local tidak pernah ikut ter-commit — dan memang tidak boleh. Nilainya harus didaftarkan ulang di dashboard platform.
Yang sering terlupa: prefiks. Variabel hanya sampai ke kode browser kalau namanya diawali prefiks yang benar:
| Tooling | Prefiks wajib |
|---|---|
| Vite | VITE_ |
| Next.js | NEXT_PUBLIC_ |
| Create React App | REACT_APP_ |
| Astro | PUBLIC_ |
| Nuxt | lewat runtimeConfig.public |
Tanpa prefiks, variabel hanya tersedia saat build dan di sisi server — bukan di browser.
Prefiks itu berarti nilainya ikut ter-bundle dan bisa dibaca siapa pun lewat DevTools. Jangan pernah menaruh API key rahasia di variabel berprefiks publik.
6. Aset 404, halaman tampil polos tanpa CSS
Situs terbuka tapi tanpa gaya sama sekali, dan Console penuh 404 untuk berkas .css dan .js.
Ini masalah base path, dan paling sering terjadi di GitHub Pages karena situsnya berada di subfolder /nama-repo/, bukan di root domain.
Di vite.config.js:
export default defineConfig({
base: '/nama-repo/',
})
Untuk Astro, isi site dan base di astro.config.mjs. Untuk Hugo, isi baseURL. Kalau pakai custom domain di root, nilainya cukup /.
7. Build kehabisan memori
FATAL ERROR: Reached heap limit Allocation failed
JavaScript heap out of memory
Naikkan batas memori Node lewat build command:
NODE_OPTIONS=--max-old-space-size=4096 npm run build
Kalau masih kena, biasanya ada yang tidak beres di kodenya: mengimpor seluruh library ikon padahal cuma pakai lima, atau memproses ratusan gambar besar saat build. Perbaiki sumbernya, jangan cuma menaikkan batas.
8. Build timeout
Netlify memutus build di sekitar 15 menit, Vercel 45 menit di paket gratis. Kalau kena, penyebab paling umum adalah pemrosesan gambar yang tidak di-cache atau dependensi yang di-install ulang dari nol tiap kali.
Pastikan package-lock.json ter-commit supaya cache dependensi bekerja, dan pindahkan optimasi gambar ke proses terpisah yang hasilnya ikut di-commit.
9. Konflik peer dependency
npm ERR! ERESOLVE unable to resolve dependency tree
Solusi cepatnya memang --legacy-peer-deps, tapi itu menyembunyikan masalah. Coba dulu perbarui paket yang bentrok ke versi yang saling kompatibel. Kalau memang harus dipaksa, simpan di .npmrc supaya konsisten antara lokal dan server:
legacy-peer-deps=true
10. Halaman putih tanpa pesan error
Buka DevTools lalu lihat Console. Halaman putih hampir selalu berarti ada JavaScript yang gagal sebelum aplikasi sempat me-render.
Tiga penyebab paling sering: base path salah (lihat nomor 6), environment variable yang dipakai bernilai undefined lalu diakses propertinya, atau kode yang menyentuh window dan document saat pre-render di server. Untuk yang terakhir, bungkus dengan pengecekan:
if (typeof window !== 'undefined') {
// kode yang butuh browser
}
11. Mixed content
Mixed Content: The page at 'https://...' was loaded over HTTPS,
but requested an insecure resource 'http://...'
Ada aset yang dimuat lewat http:// di halaman https://, dan browser memblokirnya. Cari semua kemunculannya di kode:
grep -rn "http://" src/
Ganti jadi https://. Untuk aset milik sendiri, pakai path relatif seperti /gambar/foto.jpg saja.
12. CORS saat memanggil API
Access to fetch at '...' has been blocked by CORS policy
Ini harus diperbaiki di server API, bukan di frontend. Server perlu mengirim header Access-Control-Allow-Origin yang mengizinkan domainmu.
Kalau API-nya milik orang lain dan kamu tidak bisa mengubahnya, panggil lewat serverless function di sisimu sebagai perantara — permintaan server ke server tidak terkena aturan CORS.
13. Domain sudah diarahkan tapi belum terbuka
DNS butuh waktu menyebar — biasanya menit, kadang sampai 48 jam. Cek dulu apakah recordnya sudah benar:
dig domainku.com +short
nslookup domainku.com
Kalau hasilnya sudah menunjuk ke platform yang benar tapi browsermu masih membuka halaman lama, itu cache DNS lokal. Coba lewat jaringan lain atau mode penyamaran.
14. SSL pending tidak selesai-selesai
Sertifikat baru bisa diterbitkan setelah DNS mengarah dengan benar. Kalau macet lebih dari beberapa jam, penyebab tersering adalah record CAA di domainmu yang melarang penerbit sertifikat yang dipakai platform.
dig domainku.com CAA +short
Kalau ada isinya dan tidak memuat letsencrypt.org, tambahkan atau hapus record itu. Penyebab lain: proxy Cloudflare (ikon awan oranye) aktif di depan platform lain, yang membuat verifikasi gagal.
15. Serverless function melebihi batas ukuran
Error: The Serverless Function exceeds the maximum size limit
Ada dependensi besar yang ikut ter-bundle ke dalam function. Tersangka langganan: puppeteer, sharp, SDK cloud lengkap, atau library yang sebetulnya hanya dipakai saat build.
Impor hanya bagian yang dipakai — import { format } from 'date-fns', bukan seluruh paket — dan pastikan paket build-time ada di devDependencies, bukan dependencies.
Cara membaca log build
Kalau errormu tidak ada di daftar ini, tiga kebiasaan ini biasanya cukup:
- Cari error pertama, bukan yang terakhir. Satu kegagalan biasanya memicu belasan pesan turunan. Yang paling atas itu penyebabnya.
- Jalankan perintah build yang sama persis di lokal. Bukan
npm run dev, tapinpm run build— lalu sajikan hasilnya dengannpx serve dist. Banyak error hanya muncul di mode produksi. - Hapus
node_modulesdan install ulang sebelum menyimpulkan. Menjalankanrm -rf node_modules package-lock.jsonlalunpm installmenyingkirkan kemungkinan lingkungan lokalmu yang kotor.
Untuk masalah yang khusus platform tertentu, lihat panduan deploy per platform di daftar artikel.
Kalau kamu baru mulai dan ingin menghindari error ini sejak awal, mulai dari panduan lengkap deploy website.