Netlify Deployments Fix 6 min read

Netlify Deploy Failed? How to Fix Build Errors and Common Issues

Troubleshoot Netlify deployment failures — exit code 2 Node version mismatch, Page Not Found after SPA deploy, environment variables not loading in production, redirect rules, and function timeout errors.

Netlify live status

Netlify — live status

Updated every 5 minutes · Full incident history →

Full status →

Common errors and fixes

Build Failed: exit code 2 (Node Version Mismatch)

The most common cause of build.command returning exit code 2 is Netlify using an old Node.js version that your project does not support. Netlify defaults to Node 18 but your local machine may run Node 20 or 22. The fix is to pin the version:

# Option 1: add .nvmrc to your repo root
echo "20" > .nvmrc

# Option 2: set an environment variable in Netlify dashboard
# Site settings → Environment Variables → New variable
# Key: NODE_VERSION
# Value: 20
  • .nvmrc wins: Netlify reads .nvmrc automatically — a file containing just 20 in your repo root is all you need.
  • netlify.toml alternative: you can also set [build.environment] NODE_VERSION = "20" directly in netlify.toml if you prefer keeping it in version control alongside your build config.
  • Check the build log: scroll to the top of the Netlify build log — it prints the Node version being used on the first few lines. If it does not match your local version that is the cause.

Page Not Found After SPA Deploy

If your React, Vue, or Svelte app deploys successfully but every route except the root returns a 404, Netlify is trying to serve a real file for each path instead of letting your client-side router handle it. You need a redirect rule:

# _redirects file in your publish directory (e.g., public/ or dist/)
/* /index.html 200

# OR in netlify.toml at the repo root:
[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200
Important: the _redirects file must be in your publish directory (the folder Netlify deploys), not in the repo root. For Vite projects that is typically public/.
  • Status 200 vs 301: use 200 (rewrite), not 301 (redirect) — a 301 would change the URL in the browser and break the router.
  • netlify.toml vs _redirects: if both exist, netlify.toml redirects take precedence. Avoid duplicating the same rule in both files.

Environment Variables Missing in Production

Netlify never reads your .env or .env.local files in production builds — those files should be in .gitignore and never committed. All production variables must be set in the Netlify dashboard:

# Netlify dashboard path:
# Site settings → Environment Variables → Add a variable
#
# Example variables:
# VITE_API_URL   = https://api.example.com   (exposed to browser via Vite)
# DATABASE_URL   = postgres://...             (server-only, Functions only)
# API_SECRET_KEY = sk-...                     (server-only, never prefix with VITE_)
  • VITE_ prefix: variables must be prefixed with VITE_ (for Vite) or REACT_APP_ (for CRA) to be inlined into the browser bundle at build time. Unprefixed variables are only available in Netlify Functions.
  • Redeploy required: after adding or changing a build-time variable you must trigger a new deploy — existing deployed builds do not update automatically.
  • Deploy contexts: Netlify lets you set different variable values per context (production, deploy previews, branch deploys) — useful for pointing preview deploys at a staging API.

Function Timeout and Size Limits

Netlify has three function types with very different limits. Choosing the wrong type is a common source of timeout errors:

Type Timeout Use for
Serverless Function 10 s API routes, form handlers
Edge Function 50 ms CPU Auth middleware, geo routing
Background Function 15 min Webhooks, image processing
# Background function naming convention:
# netlify/functions/send-email-background.js
#                                  ^^^^^^^^^
# The -background suffix makes Netlify treat it as a background function.
# Your handler returns 202 immediately; the function continues running.

exports.handler = async (event) => {
  // This can run for up to 15 minutes
  await longRunningTask();
  return { statusCode: 200 };
};
  • 50 MB size limit: Netlify Functions have a 50 MB zipped size limit per function. If you include large dependencies (Puppeteer, Sharp, ML models), you will hit this. Move large assets to an external CDN or use Netlify Large Media for binary assets.
  • Edge Functions run Deno: Edge Functions use the Deno runtime — they cannot use Node.js built-ins or npm packages that depend on them. Use the netlify/edge-functions/ directory and Deno-compatible imports.

Large Media and Slow Builds

Committing large binary files (images, videos, fonts) to your Git repo slows every Netlify build because the entire repo is cloned on each deploy. Options:

  • Netlify Large Media: Git LFS-backed storage for binary assets — install the Netlify CLI plugin and run netlify lm:setup to migrate existing tracked files.
  • External CDN: for large media at scale (video, audio, large image libraries) use Cloudinary, Bunny.net, or Cloudflare R2 and reference assets by URL rather than bundling them.
  • Build cache: Netlify caches node_modules between builds — if your build is still slow check whether a postinstall script or a heavy npm run build step is the bottleneck rather than the install phase.
🔔

Know when Netlify has an outage

Free email alerts. Star Netlify on Prismix — no credit card needed.

FAQ

Why does my Netlify build fail with exit code 2?

Exit code 2 almost always means Node version mismatch. Add a .nvmrc file containing 20 to your repo root, or set NODE_VERSION=20 in Site settings → Environment Variables. Check the top of the build log to see which Node version Netlify is actually using.

Why do I get Page Not Found after a successful Netlify deploy?

Single-page apps need a catch-all redirect rule. Add a _redirects file to your publish directory with the line /* /index.html 200. Make sure the file is in the publish directory (e.g., dist/ or public/), not the repo root.

What are the timeout limits for Netlify Functions?

Serverless Functions time out after 10 seconds. Edge Functions have a 50 ms CPU time limit per request. Background Functions (filename ending in -background.js) can run up to 15 minutes and return 202 immediately while processing asynchronously.

How do I set environment variables in Netlify for production?

Go to Site settings → Environment Variables in the Netlify dashboard and add each variable there. Never commit .env files. Trigger a new deploy after adding build-time variables so the next build picks them up.

Monitor related services