Why Is My NextJS Middleware Not Running? Common Pitfalls and How to Fix Them
NextJS middleware only executes for Edge runtime requests that match the file's matcher pattern, and it fails silently when the file is misplaced, the matcher is incorrect, or the runtime is inadvertently set to Node.js.
NextJS middleware provides a powerful way to intercept requests at the Edge, but developers often find their middleware.ts file appears to be ignored. According to the vercel/next.js source code, this typically happens when the middleware pipeline—spanning build-time compilation, route matching, and runtime execution—is misconfigured at any stage.
Common Reasons NextJS Middleware Fails to Trigger
Incorrect File Location
The framework searches for middleware.ts or middleware.js specifically at the project root (or src/ directory if using a custom source folder). Placing the file inside app/ or pages/ subdirectories causes it to be ignored entirely, as the build system only scans the root for this specific filename.
Matcher Configuration Errors
The export const config matcher determines which routes trigger the middleware. If the pattern fails to match your test URL, the middleware skips execution silently. The matching logic is implemented in packages/next/src/shared/lib/router/utils/middleware-route-matcher.ts, which uses path-to-regexp style patterns.
Runtime Environment Mismatch
Middleware requires the Edge runtime. If your configuration or deployment inadvertently uses Node.js runtime (runtime: 'nodejs'), the middleware will not execute. This is controlled during the build process by packages/next/src/build/webpack/plugins/middleware-plugin.ts and the dev server adapters in middleware-webpack.ts or middleware-turbopack.ts.
Missing Default Export
The middleware file must export a default function. Without export default function middleware(req) { ... }, the runtime finds no handler to invoke, causing the request to proceed as if no middleware exists.
Build and Deployment Issues
Using next export for static site generation drops middleware entirely, as it requires a server runtime. Additionally, stale build artifacts in the .next folder can cause old bundles to be served without recent middleware changes.
How the NextJS Middleware Pipeline Works
Understanding the execution flow helps diagnose why middleware appears silent. According to the vercel/next.js source:
- Build Phase:
packages/next/src/build/webpack/plugins/middleware-plugin.tslocatesmiddleware.ts, compiles it for the Edge runtime, and generates a middleware manifest. - Development Server:
packages/next/src/server/dev/middleware-webpack.ts(Webpack) ormiddleware-turbopack.ts(Turbopack) injects the compiled Edge bundle into the request pipeline. - Runtime Execution: For each request, the Edge runtime loads the manifest and runs the matcher from
packages/next/src/shared/lib/router/utils/middleware-route-matcher.ts. If the URL matches, it executes the exported middleware function with aNextRequestobject.
If any stage fails—such as a matcher returning false or a missing Edge runtime bundle—the request proceeds without triggering your code.
Debugging NextJS Middleware Issues
Add logging to verify execution:
// middleware.ts
import { NextResponse } from 'next/server'
export const config = {
matcher: ['/api/:path*', '/dashboard/:path*']
}
export default function middleware(req) {
// This logs to the terminal running `next dev`, not the browser console
console.log('Middleware triggered for:', req.nextUrl.pathname)
return NextResponse.next()
}
If you see no output in your terminal, the matcher is not matching or the file is in the wrong location.
Summary
- Place
middleware.tsat the project root orsrc/folder only; nested locations are ignored. - Verify your
matcherpatterns using the logic inmiddleware-route-matcher.tsto ensure they capture your target routes. - Confirm the Edge runtime is active; Node.js runtime or
next exportdeployments skip middleware entirely. - Check for a default export in your middleware file and clear stale
.nextbuild artifacts when troubleshooting.
Frequently Asked Questions
Why is my middleware.ts file being ignored?
Your middleware.ts file is likely in the wrong directory or missing a default export. NextJS only recognizes middleware at the project root or src/ directory. Additionally, if your export const config matcher excludes the URL you are testing, the middleware will not run.
Does NextJS middleware run on every request?
No, NextJS middleware only runs on requests that match the configured matcher pattern and are handled by the Edge runtime. Static assets, API routes explicitly configured for Node.js, and requests in statically exported sites do not trigger middleware.
How do I test if my middleware is working?
Add a console.log statement at the start of your middleware function and run next dev. Check your terminal output (not the browser console) when visiting the target route. If no log appears, verify your file location and matcher configuration against the source code in packages/next/src/shared/lib/router/utils/middleware-route-matcher.ts.
Can I use Node.js APIs in NextJS middleware?
No, NextJS middleware executes in the Edge runtime, which does not support Node.js-specific APIs like fs or path. You must use Web-standard APIs such as fetch, Request, Response, and NextResponse from next/server. Attempting to import Node modules will cause the middleware build to fail or the runtime to error.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →