Fix Next.js 'Cannot Have a Negative Time Stamp' Error

Why Turbopack throws "cannot have a negative time stamp" on notFound() and redirect(), the upstream React bug behind it, and three workarounds that hold.

Mahdi Ben RhoumaMahdi Ben Rhouma · Updated

You refresh a page on your Turbopack dev server — usually one that just called notFound() — and the dev overlay slams this in your face:

text
Unhandled Runtime Error
 
Failed to execute 'measure' on 'Performance':
'NotFound' cannot have a negative time stamp.

The quoted component name varies: 'NotFound', 'Page', 'SlugPage' for a [slug]/page.tsx route, or 'AdministrationPage [Prerender]' behind an auth guard. On Firefox the wording differs — Performance.measure: Given attribute end cannot be negative — but it is the same failure. The stack trace usually points into react-server-dom-turbopack-client.browser.development.js: the error has mostly been reported under next dev with Turbopack, although a September 2026 comment reproduced it under next dev --webpack too. Your production build is fine.

The bug is tracked upstream in vercel/next.js issue #86060, first reported against Next.js 16.0.2-canary with React 19.2.0 and reproduced by commenters on stable 16.1.1, 16.1.6 and, in September 2026, 16.3.3. It is still open as of October 2026. Below are the triggers in descending order of how often they show up in that thread, each with a confirmation test and a fix.

Cause 1: notFound() on a dynamic or catch-all route#

This is the original report and the most common trigger. React's development-only performance track initialises an internal childrenEndTime variable to -Infinity. When notFound() interrupts rendering before any children are processed, that variable is never updated — and React then calls performance.measure() with the still-negative value. The happy path guards against this (0 <= childrenEndTime); the abort and rejection paths do not, which is exactly what PR #88688 identified.

Confirm it: hit a URL that does not exist under a dynamic segment — /blog/does-not-exist for a [slug] route with notFound() in it. If the overlay error names your route's component ('SlugPage', 'NotFound'), this is your cause. One commenter noted the error is intermittent but becomes near-certain after editing not-found.tsx and refreshing a few times — HMR makes the race more likely.

Fix: a commenter on the issue resolved it by moving not-found.tsx out of the dynamic route folder into its parent directory. The catch-all still resolves the 404 correctly (Next.js walks up the tree for the nearest not-found file), but the render-abort no longer happens inside the segment whose timing React is measuring. If restructuring is not an option, jump to the workarounds section.

Cause 2: redirect() in a Server Component#

The second cluster of reports involves redirect() rather than notFound() — typically auth or admin guards that redirect before the page finishes rendering:

tsx
// app/[locale]/admin/page.tsx
export default async function AdministrationPage() {
  const session = await getSession()
  if (!session?.user?.isAdmin) {
    redirect('/login') // ← interrupts the render mid-measurement
  }
  return <AdminDashboard />
}

The mechanism is the same as Cause 1: the redirect aborts the component, its childrenEndTime stays at its negative initial value, and React passes that value to performance.measure() — the case the open React PR #37563 guards against, reproduced by its author through a Next.js auth redirect. A February 2026 comment on the issue pinned the throwing call to the flushComponentPerformance function at line 3776 of the Turbopack development bundle.

Confirm it: the error names the guarded page (often with a [Prerender] suffix) and fires on the initial load of a route that conditionally redirects — not on a 404.

Fix: there is no code-level fix on your side that keeps the redirect logic intact; the guard is correct, React's dev instrumentation is not. Use one of the workarounds below. Do not move the redirect into a useEffect just to silence a dev-only overlay — that would ship a real flash-of-content regression to users to hide a cosmetic error.

Cause 3: next/dynamic with ssr: false on an older React#

An earlier variant of the same error came from next/dynamic components with { ssr: false } inside client components. There, a fiber that never completed its work phase kept its initial startTime of -1.1, and React's logComponentMount fed that into performance.measure(). React fixed this one upstream in facebook/react PR #32823, merged in April 2025.

Confirm it: you are on a React 19 build from before mid-2025 (check npm ls react) and the error appears when a dynamic(() => import(...), { ssr: false }) component mounts — no notFound() or redirect() involved.

Fix: upgrade Next.js, which pins a patched React. On any 16.x release this variant is already fixed, so your error is Cause 1 or 2.

Cause 4: Firefox timer precision makes it worse#

A July 2026 comment on the issue added a browser dimension: Firefox ships privacy.reduceTimerPrecision enabled by default, which rounds performance.now() values. That rounding makes tiny negative deltas between two nearly simultaneous timestamps far more likely, so Firefox users hit the error more often than Chrome users on identical code — one Next.js maintainer could not even reproduce the original report in Chrome on macOS.

Confirm it: the error fires in Firefox but not Chrome on the same route, with Firefox's own wording (Given attribute end cannot be negative).

Fix: none needed beyond the workarounds below — but if your team is split on "works on my machine", the browser difference is why. This is also worth knowing before you burn an afternoon profiling: the measurement that crashes is React's internal component track, not anything from your own code, so tools from our Next.js performance optimisation guide will show nothing wrong.

Where the fix stands upstream#

As of October 2026:

  • Issue #86060 is open and triaged by the Next.js team (labelled for their internal tracker).
  • PR #88688, which added the missing 0 <= childrenEndTime guard to the error and abort paths in Next.js's vendored React files, was closed unmerged in January 2026. Maintainer @eps1lon's reasoning: patching the compiled output masks the symptom, and the real fix belongs in facebook/react.
  • The ssr: false variant was fixed in react#32823 (April 2025) and has long since shipped inside Next.js.
  • A fix for the notFound()/redirect() variant is proposed in React itself, react/react#37563, still open as of October 2026; it skips aborted and errored component entries whose children end time is still negative.
  • No stable Next.js release fixes that variant yet: the error was reproduced on 16.3.3 in September 2026, and the latest release on npm is 16.4.0. Upgrading is worth a try after each React sync, but do not count on it.

So unlike a stuck Turbopack compile, which clearing .next usually fixes, this one has no fix on your side yet.

Workarounds while you wait#

Three options, all confirmed by commenters on the issue, all dev-only:

1. Run the dev server on webpack. Several people independently reported that this makes the error go away. It is a mitigation, not a guarantee: the same unguarded call exists in React's webpack client bundle (PR #88688 patched both), and one commenter reproduced the error under --webpack on 16.3.3:

bash
next dev --webpack

The trade-off is real — you give up Turbopack's faster HMR — so treat it as the fallback, not the default. (Note the flag is --webpack; there is no environment variable that disables Turbopack.)

2. Relocate not-found.tsx. If your trigger is Cause 1, moving the file from inside the dynamic segment (app/[slug]/not-found.tsx) up to its parent (app/not-found.tsx) resolved it for at least one reporter, with 404 behaviour unchanged.

3. Patch performance.measure in development. The first comment on the issue shares this approach: wrap the native method and swallow only the negative-timestamp failure. Load it from your root layout, guarded so it can never reach production:

tsx
// instrumentation-client.ts (or imported in app/layout.tsx)
if (process.env.NODE_ENV === 'development') {
  const original = performance.measure.bind(performance)
  performance.measure = ((...args: Parameters<typeof original>) => {
    try {
      return original(...args)
    } catch (e) {
      if (e instanceof Error && e.message.includes('negative time stamp')) {
        return undefined as unknown as PerformanceMeasure
      }
      throw e
    }
  }) as typeof performance.measure
}

This is the bluntest option — it also hides any legitimate negative-timestamp bug in your own instrumentation — so delete it once the upstream fix lands.

Whichever you choose, remember the scope: this error never reaches your users. The throwing code is in a *.development.js bundle that production builds exclude, which is why nobody has ever reported it from a deployed site. If you are seeing runtime errors in production, you are looking at a different failure — start with our breakdown of ChunkLoadError: Loading chunk failed, and for other dev-mode-only surprises that look scarier than they are, see why useEffect runs twice in dev.

Still stuck? Paste your error.

Paste the error message or stack trace — we check it against every fix and tool on the site.

Matching happens in your browser. When you search, a cleaned error signature is sent so we can spot errors we do not cover yet — never the raw text, your IP address or your e-mail. Do not paste passwords or keys. Details

Related fixes & guides