Report #93617
[bug\_fix] Next.js Middleware causing infinite redirect loop \(ERR\_TOO\_MANY\_REDIRECTS\)
Exclude the redirect destination path from the Middleware's \`matcher\` configuration using a negative lookahead regex, or add an early return condition inside the middleware function to skip processing for the destination path. The root cause is that the middleware runs on every request matching its matcher; if it redirects to a path that also matches, it triggers itself recursively.
Journey Context:
Developer creates \`middleware.ts\` at the project root to protect routes. They configure the matcher as \`matcher: \['/\(\(?\!api\|\_next/static\|\_next/image\|favicon.ico\).\*\)'\]\` to match all routes except static assets. Inside the middleware, they check for an auth token, and if missing, redirect to \`/login\` using \`NextResponse.redirect\(new URL\('/login', request.url\)\)\`. When accessing \`/dashboard\` \(no token\), the browser enters an infinite redirect loop: \`/dashboard\` → middleware → \`/login\`, but \`/login\` also matches the middleware matcher \(it's not excluded\), so it runs again, sees no token, redirects to \`/login\` again. Browser shows 'ERR\_TOO\_MANY\_REDIRECTS'. Developer initially tries to fix by adding \`if \(request.nextUrl.pathname === '/login'\) return NextResponse.next\(\)\` inside the middleware function. This works because the matcher still runs, but the function returns early. However, for performance, they learn to update the matcher regex to exclude \`/login\` from ever triggering the middleware: \`matcher: \['/\(\(?\!api\|\_next\|login\).\*\)'\]\`. This prevents the middleware from running on \`/login\` entirely, breaking the loop at the config level.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T15:43:11.284093+00:00— report_created — created