Error: NEXT_REDIRECT
Next.js · updated 2026-11-03
Seen in logs, error trackers or a catch block when redirect() or permanentRedirect() runs inside a try/catch in a Server Component, Server Action or route handler. Next.js uses the thrown error to stop rendering and send the redirect; catching it stops the redirect from happening.
Error: NEXT_REDIRECT
at getRedirectError (node_modules/next/dist/client/components/redirect.js:49:19)
at redirect (node_modules/next/dist/client/components/redirect.js:59:11)
at saveOrder (app/orders/actions.ts:18:5) {
digest: 'NEXT_REDIRECT;replace;/orders/123;307;'
}Quick fix
Move redirect() after the try/catch, so only your own work is inside the try. If you need a catch-all, call unstable_rethrow(err) (or check isRedirectError) at the top of the catch so Next.js's redirect error passes through.
- Find the redirect() call and the try/catch around it.
- Do the work inside try, store the result, and call redirect() after the block.
- If the catch must stay, start it with unstable_rethrow(error) from 'next/navigation'.
- Make sure your error tracker or logging does not report NEXT_REDIRECT and NEXT_NOT_FOUND as failures.
'use server';
import { redirect, unstable_rethrow } from 'next/navigation';
export async function saveOrder(form: FormData) {
let id: string;
try {
id = await db.orders.create(parse(form));
} catch (err) {
unstable_rethrow(err); // lets NEXT_REDIRECT / notFound() through
return { error: 'Could not save the order' };
}
redirect(`/orders/${id}`); // outside the try
}Why it happens
redirect() inside try
The most common case: a Server Action saves data and redirects in the same try block. The catch receives NEXT_REDIRECT, logs it as an error and returns, so the user stays on the form.
A generic error handler around the whole action
Wrappers that catch everything to return { error } swallow redirect(), notFound() and other Next.js control-flow errors the same way.
Error tracking that reports every thrown error
Even when the redirect works, a tracker hooked into the catch can file NEXT_REDIRECT as an error. It is control flow, not a failure, and should be filtered out.
Other fixes
- notFound() works the same way (NEXT_HTTP_ERROR_FALLBACK or NEXT_NOT_FOUND); the same rethrow fixes it.
- In Client Components, redirect from event handlers with useRouter().push() instead; redirect() is meant for server code and rendering.
Same error, other wording
- Error: NEXT_REDIRECT;replace;/login;307;
- Error: NEXT_HTTP_ERROR_FALLBACK;404
- Error: NEXT_NOT_FOUND
Let your coding agent catch the next one
Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:
> Find where NEXT_REDIRECT is being caught or reported in our Next.js app, show me the try/catch blocks around redirect() or notFound(), and move the redirect out or rethrow it with unstable_rethrow.
Related errors
- Route "/orders/[id]" used `params.id`. `params` should be awaited before using its...
- Dynamic server usage: Route /x couldn't be rendered statically because it used `headers`.
- An error occurred in the Server Components render. The specific message is omitted in...
References: Next.js docs: redirect, Next.js docs: unstable_rethrow