Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

static route with revalidation doesn't switch between 404 and 200 status codes correctly #63478

Open
tdanecker opened this issue Mar 19, 2024 · 9 comments
Labels
bug Issue was opened via the bug report template.

Comments

@tdanecker
Copy link
Contributor

Link to the code that reproduces this issue

https://github.com/tdanecker/404-test

To Reproduce

Use a static route (/ in the linked repo) with const export revalidate = <some number> which, depending on a fetch request, either returns notFound() or the actual content.

In the linked repo:

  1. Start mocked 404 API responses: docker-compose up response-404
  2. Start app: npm run build && npm run start
  3. Observe responses:
    first response: 404 Page, but status code 200 ❌
    subsequent responses after revalidation: 404 Page, status code 404 ✅
  4. Switch mocked API response to 200: docker-compose up response-200
  5. Observe responses:
    first response: 404 Page, status code 404 (old stale response)
    subsequent responses: correct page content, but 404 status code ❌

Current vs. Expected behavior

Current:

  • Next.js first returns a 200 status code for a notFound / 404 page.
  • The route doesn't recover correctly from a notFound / 404 page. It sends back the correct content but gets stuck at the 404 status code.

Expected:

  • The first response returns the correct 404 status code for notFound.
  • After the content is available, the route responds with the content and a 200 status code.

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #25~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Feb 20 16:09:15 UTC 2
  Available memory (MB): 31695
  Available CPU cores: 16
Binaries:
  Node: 20.11.0
  npm: 10.2.4
  Yarn: 3.6.1
  pnpm: 7.33.5
Relevant Packages:
  next: 14.2.0-canary.31 // Latest available version is detected (14.2.0-canary.31).
  eslint-config-next: 14.1.3
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.4.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

App Router

Which stage(s) are affected? (Select all that apply)

next start (local), Other (Deployed)

Additional context

On our production setup, after some time (sometimes hours), the status code seems to recover to a correct 200 status code. My theory is, that it recovers once the whole route got ejected from the full route cache.

@tdanecker tdanecker added the bug Issue was opened via the bug report template. label Mar 19, 2024
@antimonad
Copy link

antimonad commented Mar 25, 2024

We are encountering this issue on our classifieds site we are currently migrating to next.js

@tdanecker
Copy link
Contributor Author

#63731 fixes the first part of the issue. On the first request, the notFound response now correctly responds with a 404 status code.

@felixmusmann
Copy link

We are observing this issue as well on one of our sites, that we migrated to the app router.

@osterbaer

This comment has been minimized.

@DjilanMouhous
Copy link

@osterbaer Yeah I am still encountering this issue in our production environment, which is causing persistent status code errors on some paths

@mirel-v
Copy link

mirel-v commented Oct 9, 2024

I'm experiencing the same issue in my project. Any advice or workarounds would be greatly appreciated!

@tdanecker
Copy link
Contributor Author

The only workaround we found is to fully disable the Next.js cache by setting a cacheHandler that does nothing (and just cache at the CDN). You can also switch the route from a static route into a dynamic route if you don't need it to be cached.

None of those workarounds are particularly pleasant. We are dependent on Vercel to fix it.

@ARochniak
Copy link

We have resolved the stale 404 status issue by calling revalidatePath from the route handler. In our case, the route handler is a webhook that is triggered whenever there are changes to the content on the CMS side.

@felixmusmann
Copy link

felixmusmann commented Oct 10, 2024

Fully disabling the cache is not really an option for us. After some experimenting, we are now also working on a workaround involving the revalidatePath method. It confuses me though, that the on-demand revalidation seems to behave differently than the time based revalidation. Is there a reason behind this?

Nevertheless, this issue should be given a higher priority, since it might also affect the websites SEO performance. We are already seeing 404 error codes popping up in the Google Search Crawler. This is the case for our landing page as well as other pages that are main entry points for our users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

No branches or pull requests

7 participants