When a 504, 413, or build failure appears in production, you panic. But Vercel errors have mostly fixed categories and causes, so you can crush them quickly with a reverse look-up. This article, faithful to Vercel's official error list and Functions limitations, is a practical collection organizing the errors that really appear in the field, by cause.
For the big picture, see the Vercel production-operations guide.
First: pinpoint the symptom (don't guess)
When you see an error code, before fixing blindly, take primary-source information from the logs.
- Observability tab: pinpoint which route is raising the error rate/latency (observability).
- Runtime Logs: check the relevant function's logs and stack trace.
- Build Logs: build failures all appear here.
x-vercel-cache/ response headers: the state of caching and routing.
Errors fall into roughly 5 categories.
| Category | Representative code | Where it appears |
|---|---|---|
| Function | FUNCTION_INVOCATION_TIMEOUT(504), FUNCTION_PAYLOAD_TOO_LARGE(413), FUNCTION_INVOCATION_FAILED(500) | At runtime |
| Deployment/build | Missing public directory, Missing build script, FALLBACK_BODY_TOO_LARGE | At build time |
| Routing | Dynamic-route 404, Invalid route source pattern | At request time |
| Request | Body overrun, auth/protection | At the entrance |
| Configuration | functions vs builds conflict, invalid Edge Config connection string | At deploy time |
Function errors
FUNCTION_INVOCATION_TIMEOUT (504)
Cause: the function didn't complete within maxDuration (default 300s, Pro/Ent max 800s). Typical of long synchronous processing, infinite waits, or external-API hangs.
Fix:
// ① まず maxDuration を用途に合わせて明示(だらだら生かさない)
export const maxDuration = 60;
// ② 長時間処理は関数に抱えず Workflows / キューへ分離
// (数分を超える処理を同期HTTPで持たない)
export async function POST(request: Request) {
const job = await enqueueHeavyJob(await request.json()); // すぐ返す
return Response.json({ jobId: job.id }, { status: 202 });
}
// ③ 進捗を返したいならストリーミングで初動を速く
Attach a timeout and AbortController to external API calls to cut hangs yourself. For separating heavy processing, see the Functions guide.
FUNCTION_PAYLOAD_TOO_LARGE (413)
Cause: the request body or response body exceeded 4.5MB. Typical of receiving file uploads in a function.
Fix: send uploads directly to Vercel Blob (client upload), bypassing the function.
// 旧:関数で multipart を受ける → 4.5MB で死ぬ
// 新:client upload でブラウザから Blob へ直接(転送課金も回避)
import { upload } from "@vercel/blob/client";
const blob = await upload(file.name, file, {
access: "public",
handleUploadUrl: "/api/upload", // トークン発行+認可だけサーバーで
});
Details in the storage/Blob guide. For a large response, change to paging, streaming, or delivery via Blob.
FALLBACK_BODY_TOO_LARGE (ISR page too large)
Cause: when an ISR/prerender response exceeds 20MB, the page doesn't render in production. Caused by huge embedded data, inline images, or redundant JSON.
Fix: make the page output lighter. Fetch data in splits / lazy-load, externalize images with next/image, and trim unnecessary inline JSON.
FUNCTION_INVOCATION_FAILED (500)
Cause: an uncaught exception inside the function. DB connection failure, unset env, null reference, etc.
Fix: check the stack trace in Runtime Logs. Catch exceptions at the boundary and return a meaningful error instead of a 500. Since unset env is common, validate required env with Zod at startup.
Build failures
For build failures, the cause all appears in Build Logs. Frequent ones, by cause.
Wrong output directory / build script
Missing public directory / Missing build script
Cause: the output directory is wrong, there's no build script, or the root directory (monorepo) is misspecified.
Fix:
- Check Output Directory / Build Command / Root Directory in Project Settings.
- Run the same build command locally and confirm the artifact is generated in the output location (the fastest isolation).
- For a monorepo, set Root Directory to the app's path.
Function pattern mismatch / config conflict
Unmatched function pattern / Conflicting functions and builds
Cause: the functions glob in vercel.json doesn't match files under api/, or you're using functions and builds together (not allowed).
Fix:
// ❌ api/ 外を指している
{ "functions": { "users/**/*.js": { "maxDuration": 30 } } }
// ✅ api/ 配下を指す(Next.js は pages/api/** も可)
{ "functions": { "api/users/**/*.js": { "maxDuration": 30 } } }
Use only one of functions or builds. As a rule, use functions (which allows memory settings, etc.). In Next.js, what you can set in functions is only memory and maxDuration (the rest is auto-managed by Next.js).
Route syntax error
Invalid route source pattern
Cause: source/rewrites/redirects in vercel.json are path-to-regexp syntax, not raw regex. A negative lookahead must be wrapped in a group.
// ❌ "source": "/feedback/(?!general)"
// ✅ "source": "/feedback/((?!general).*)"
Dependency/package-manager inconsistency
Cause: ERR_PNPM_UNSUPPORTED_ENGINE (engines.pnpm mismatch), a lockfile-vs-package-manager mismatch, or a Node version difference.
Fix: align engines/packageManager in package.json, or enable Corepack. Node is 24 LTS by default (18 is deprecated). Put @vercel/speed-insights/@vercel/analytics in the package.json dependencies, not global (a frequent monorepo issue).
Routing and 404
A dynamic route returns 404
Cause: generateStaticParams doesn't return the target, the dynamic/dynamicParams setting, or a path that doesn't exist at build time.
Fix:
// 事前生成しないパスもオンデマンドで通す
export const dynamicParams = true; // 既定 true(false だと未生成は404)
export async function generateStaticParams() {
// 少なくとも代表パスを返す。残りはオンデマンド生成(ISR)
return (await getPopularSlugs()).map((slug) => ({ slug }));
}
For ISR behavior, the caching/ISR guide.
Doesn't display on a custom domain / DNS
Cause: DNS records (A/CNAME) unset, awaiting propagation, or the domain isn't added.
Fix: confirm the necessary records with vercel domains inspect <domain>. Keeping the TTL short speeds up switching/confirmation.
Environment variables "don't take effect"
This isn't an error but a sticking point, and there are very many consultations about it.
- Environment-variable changes apply only to a new deployment. The existing production deployment doesn't change → redeploy.
- To read it in the browser (client), the
NEXT_PUBLIC_prefix is needed. Conversely, don't attach it to secrets. - Set the value per environment (production/preview/development). If unset on preview, only preview falls over.
- An invalid Edge Config connection string (
Invalid Edge Config connection string) means theEDGE_CONFIGenv is stale/deleted → update it.
Details in the environment-variables/secrets guide.
Cold start / slow
Cause: heavy function initialization (large dependencies, heavy work at startup), or the function executes every time on a cache miss.
Fix:
- With Fluid Compute (default), concurrency and pre-warming work, and Node 20+'s bytecode cache works.
- Do heavy startup work (large JSON parse, connection establishment) once outside the handler / lazily.
- Don't call the function in the first place — make it a
HITwith the ISR/CDN cache (caching). Confirm withx-vercel-cache. - Trim the bundle (remove unnecessary dependencies, 250MB limit).
Trouble-isolation checklist
- Took primary-source information from Observability / Runtime Logs / Build Logs (don't guess)
- 504 → make
maxDurationexplicit + separate long-running processing, timeout external APIs - 413 → uploads are client upload directly to Blob
- ISR over 20MB → lighten the page output
- Build failure → reproduce the same build locally, check output location/route/function pattern
- 404 →
generateStaticParams/dynamicParams, DNS - env not taking effect → redeploy,
NEXT_PUBLIC_, per-environment settings - Slow →
HITwith caching, Fluid, bundle reduction
Conclusion
Vercel troubleshooting can be crushed mechanically with "pinpoint the symptom with logs → category → cause → standard fix."
- Logs, not guessing (Observability / Runtime / Build Logs)
- 504 is separation, 413 is direct-to-Blob, ISR 20MB is lightening
- Build failures are local reproduction to isolate
- env is redeploy,
NEXT_PUBLIC_, per-environment settings - Cure slowness with cache HIT
I accompany you as a project through production incident investigation, permanent measures, and building out recurrence prevention. I also take spot investigations starting from the "an unexplained 504/500 is appearing" stage.
This article is based on the official documentation of the Vercel error list / Functions limitations (as of June 2026). Error codes and limits get updated, so confirm the latest in the official docs.