`notFound()` returns 200 instead of 404

Hi everyone,

I’m facing an issue with my Next.js project hosted on Vercel. I’m using Next.js 14.2.3 with the new app directory and trying to trigger a 404 HTTP status using the notFound() function from next/navigation. However, instead of returning a 404 status code, the page still returns a 200.

Here’s a simple example to reproduce the issue:

import { notFound } from "next/navigation";

export default function TestPage() {
    console.log("404 Test: notFound is being called");
    notFound();
}

When I visit the route /test, the log is correctly displayed in the terminal (404 Test: notFound is being called), but the HTTP status code remains 200 instead of 404. Testing with curl gives the following result:

curl -I http://localhost:3000/test
# Result:
HTTP/1.1 200 OK

Here’s what I’ve tried so far:

  1. I excluded potential middleware issues by completely removing any middleware from the project.
  2. I simplified my next.config.js with no custom changes
  3. Tested the behavior both in the development environment (npm run dev) and the production build (npm run build && npm start).
  4. Ensured there are no header manipulations, redirects, or caching issues in my Vercel setup.

Despite all this, the status code remains 200 even when notFound() is called. This behavior is unexpected, and I’m unsure if it’s related to the use of withBuilderDevTools or something else in my environment.

Has anyone else encountered this issue or might know what could be causing it? Could this be related to Vercel’s hosting environment or my configuration?

Any help or suggestions would be greatly appreciated—thank you so much in advance!

There’s another community post with 404 debugging tips that might be helpful. Please give these solutions a try and let us know how it goes.

A human should be around soon to offer more advice. But you can also get helpful information quickly by asking v0.

Hey @maxout ,
Hopefully here to help, I’m definitely curious to know more about your page setup. I will also share the docs related to notFound just for reference. Main note I wanted to reference:

Next.js will return a 200 HTTP status code for streamed responses, and 404 for non-streamed responses.

That could be what you are experiencing. Do you have a not-found.tsx in your /app directory?

Hey Miguel, thanks for reply.
i do have a not-found.js in my /app directory. i don’t get the difference between streamed an non-streamt response an how i can configure this. i think it’s the dymanic routing. it only seems to work with static pages but then it’s useless ;-/
hope you can help me with this and have a hint for me

i found this conservation. apparently many people encounter this problem but none of them have a solution