Diagnosing Incremental Static Regeneration Failures in Next.js Jamstack Sites
Learn how to identify and fix ISR issues in Next.js Jamstack sites, from checking revalidate values to reviewing CDN cache and serverless logs.
22 Nov 2025, 22:05 UTC

Recognizable Condition
ISR-enabled pages either return a 404 after the revalidation window or continue to serve stale HTML even after the configured interval has elapsed. In the browser you may see outdated data, and the response headers lack an updated X-Nextjs-Revalidate value or show a miss in the CDN edge cache.
Cause / Diagnostic Indicators
| Possible Cause | What to Look For |
|---|---|
| Incorrect revalidate value (non-numeric, zero, or missing) | Page never regenerates; X-Nextjs-Revalidate header absent or shows false. |
| Serverless function timeout | Function logs show Timeout or Error: Process exited before completing request after ~10s (Vercel) or similar. |
| CDN edge cache TTL too low or purge mis-configured | Requests hit CDN cache that returns stale HTML; no request reaches the origin function. |
| Missing or malformed getStaticProps/getStaticPaths | Build succeeds but runtime throws Failed to getStaticProps or returns empty props. |
| Environment variable drift between build and runtime | Data fetched in getStaticProps uses a secret that is undefined at runtime, causing fallback to stale data or error. |
Ordered Checks
- Confirm Next.js version supports ISR (>= 9.5). Run next -v locally or check package.json.
- Inspect the page’s getStaticProps return object. Ensure it contains a numeric revalidate (e.g., return { props, revalidate: 60 }) or false to disable.
- Trigger a request after the interval and examine the serverless function logs (Vercel Dashboard → Functions → Logs, Netlify → Site settings → Functions logs, or vercel logs CLI). Look for regeneration entries or timeout messages.
- Check the CDN edge cache TTL. In the provider dashboard (Vercel → Settings → Git → Edge Config, Netlify → Site settings → Cache-control) verify that the Cache-Control header includes stale-while-revalidate or a suitable max-age. If the edge TTL is shorter than the ISR interval, the CDN may serve stale content without hitting the origin.
- Compare environment variables used at build time versus runtime. In CI, echo the variables (masked) and compare with process.env values logged in the function. A mismatch indicates drift.
- Perform a manual purge: use the provider’s purge API or dashboard to clear the edge cache for the page URL, then request the page again. Watch the function logs for a new regeneration attempt and verify the response header shows the expected revalidate value.
Fixes Tied to Findings
- If revalidate is missing or non-numeric, edit the page file to return a valid number (e.g., return { props, revalidate: 60 }). For pages that should never regenerate, set revalidate: false.
- When logs show timeouts, increase the serverless function timeout (Vercel: functions.[name].maxDuration in vercel.json; Netlify: [[plugins]] with netlify-plugin-functions-timeout) or optimize the data fetch (use cache: 'no-store' only if needed, move heavy work to background jobs).
- If the CDN is serving stale content, adjust edge cache settings: set Cache-Control: s-maxage=1, stale-while-revalidate=59 for a 60-second ISR window, or purge the cache after each successful regeneration via a webhook.
- For dynamic routes, ensure getStaticPaths returns fallback: 'blocking' or fallback: true with a matching revalidate in getStaticProps. This prevents 404s on first request after a rebuild.
- Align environment variables: add missing secrets to the CI environment (e.g., Vercel Settings → Environment Variables) and redeploy. Verify that process.env.VAR matches the value used during build.
- After applying a fix, repeat the manual purge and request cycle. Confirm that the function logs show a regeneration entry and that the response header X-Nextjs-Revalidate contains the expected numeric value.
Escalation Criteria
- Stale content persists after a manual purge and the function logs show no regeneration attempts (i.e., the request is fully served from CDN edge cache).
- Serverless functions repeatedly timeout despite increasing the timeout limit and optimizing data fetch.
- CDN configuration cannot be adjusted (e.g., limited plan) and edge TTL conflicts with ISR interval.
In these cases, involve the infrastructure team to review CDN rules, consider dedicating a separate origin for ISR endpoints, or fall back to full static generation (getStaticProps without revalidate) for the affected pages.
Verification Steps
- Run next dev locally, request the page, and check the response header X-Nextjs-Revalidate for the expected value.
- Run next build && next start and repeat the request; verify the header persists.
- On Vercel, use vercel logs --now to stream function logs while triggering a request after the ISR interval.
Limitations
- ISR requires a Node.js serverless runtime (Vercel Functions, Netlify Functions, AWS Lambda via @vercel/node, etc.). It will not work on purely static hosts that only serve pre-built files (e.g., GitHub Pages).
- Behavior of ISR can differ between Next.js versions; features like unstable_cache are experimental and may change. Always verify against the specific Next.js version in use.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.