# Why Is My NextJS Middleware Not Running? Common Pitfalls and How to Fix Them

> NextJS middleware not running? Discover common pitfalls like incorrect matchers or Node.js runtime issues and learn how to fix them. Troubleshoot your Edge runtime middleware effectively.

- Repository: [Vercel/next.js](https://github.com/vercel/next.js)
- Tags: how-to-guide
- Published: 2026-02-15

---

**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`](https://github.com/vercel/next.js/blob/main/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`](https://github.com/vercel/next.js/blob/main/middleware.ts) or [`middleware.js`](https://github.com/vercel/next.js/blob/main/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`](https://github.com/vercel/next.js/blob/main/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`](https://github.com/vercel/next.js/blob/main/packages/next/src/build/webpack/plugins/middleware-plugin.ts) and the dev server adapters in [`middleware-webpack.ts`](https://github.com/vercel/next.js/blob/main/middleware-webpack.ts) or [`middleware-turbopack.ts`](https://github.com/vercel/next.js/blob/main/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`](https://github.com/vercel/next.js/blob/main/packages/next/src/build/webpack/plugins/middleware-plugin.ts) locates [`middleware.ts`](https://github.com/vercel/next.js/blob/main/middleware.ts), compiles it for the Edge runtime, and generates a middleware manifest.
2. **Development Server**: [`packages/next/src/server/dev/middleware-webpack.ts`](https://github.com/vercel/next.js/blob/main/packages/next/src/server/dev/middleware-webpack.ts) (Webpack) or [`middleware-turbopack.ts`](https://github.com/vercel/next.js/blob/main/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`](https://github.com/vercel/next.js/blob/main/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:

```typescript
// 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`](https://github.com/vercel/next.js/blob/main/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`](https://github.com/vercel/next.js/blob/main/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`](https://github.com/vercel/next.js/blob/main/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`](https://github.com/vercel/next.js/blob/main/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.