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:

  1. Build Phase: packages/next/src/build/webpack/plugins/middleware-plugin.ts locates middleware.ts, compiles it for the Edge runtime, and generates a middleware manifest.
  2. Development Server: packages/next/src/server/dev/middleware-webpack.ts (Webpack) or middleware-turbopack.ts (Turbopack) injects the compiled Edge bundle into the request pipeline.
  3. 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 a NextRequest object.

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.ts at the project root or src/ folder only; nested locations are ignored.
  • Verify your matcher patterns using the logic in middleware-route-matcher.ts to ensure they capture your target routes.
  • Confirm the Edge runtime is active; Node.js runtime or next export deployments skip middleware entirely.
  • Check for a default export in your middleware file and clear stale .next build 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →