search
next

Fix: Middleware not running in Next.js error

Quick fix for middleware not running in Next.js. Learn how to properly configure and troubleshoot Next.js middleware.

person By Gautam Sharma
calendar_today January 8, 2026
schedule 4 min read
Next.js Middleware Authentication Routing React JavaScript

The ‘Middleware not running in Next.js’ error occurs when Next.js middleware is not properly configured, placed incorrectly, or has issues with the matcher configuration. This prevents middleware from intercepting requests as expected.


How the Error Happens

❌ Error Scenario - Wrong File Location:

// ❌ This won't work
// pages/middleware.js - ❌ Wrong location for App Router
export function middleware(request) {
  console.log('This middleware will not run'); // ❌ Won't execute
  return NextResponse.next();
}

❌ Error with Invalid Matcher:

// ❌ This won't work properly
// middleware.js
export function middleware(request) {
  return NextResponse.next();
}

// ❌ Invalid matcher configuration
export const config = {
  matcher: ['/invalid/*path'] // ❌ Syntax error in path
};

✅ Quick Fix - Proper Middleware Configuration

Solution 1: Correct Middleware File Placement

// ✅ Place middleware.js in project root
// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  console.log('Middleware is running!');
  
  // ✅ Example: Add custom header
  const response = NextResponse.next();
  response.headers.set('X-Custom-Header', 'middleware-active');
  
  return response;
}

// ✅ Configure which paths the middleware should run on
export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     */
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
};

Solution 2: Authentication Middleware

// ✅ Authentication middleware example
// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  // ✅ Check for authentication token
  const token = request.cookies.get('auth_token');
  
  // ✅ Define protected routes
  const protectedPaths = ['/dashboard', '/admin'];
  const isAuthenticated = !!token;
  
  // ✅ Redirect unauthenticated users from protected routes
  if (protectedPaths.some(path => request.nextUrl.pathname.startsWith(path)) && !isAuthenticated) {
    const url = request.nextUrl.clone();
    url.pathname = '/login';
    return NextResponse.redirect(url);
  }
  
  return NextResponse.next();
}

export const config = {
  matcher: [
    '/dashboard/:path*',
    '/admin/:path*',
    '/profile/:path*',
  ],
};

Solution 3: Conditional Middleware

// ✅ Conditional middleware with multiple checks
// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  const { pathname } = request.nextUrl;
  
  // ✅ Skip middleware for certain paths
  if (pathname.includes('/api/health')) {
    return NextResponse.next();
  }
  
  // ✅ Rate limiting example
  const ip = request.ip || request.headers.get('x-forwarded-for');
  const url = request.nextUrl.toString();
  
  console.log(`Request from IP: ${ip} to: ${url}`);
  
  // ✅ Add custom headers
  const response = NextResponse.next();
  response.headers.set('X-Response-Time', new Date().toISOString());
  
  return response;
}

export const config = {
  matcher: [
    // ✅ Match all paths except static files and API routes
    {
      source: '/(.*)',
      missing: [
        { type: 'header', key: 'next-router-prefetch' },
        { type: 'header', key: 'purpose', value: 'prefetch' },
      ],
    },
  ],
};

Solution 4: Region-Specific Middleware

// ✅ Middleware with region/country detection
// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  // ✅ Get country from headers (provided by hosting platform)
  const country = request.geo?.country || 'US';
  const pathname = request.nextUrl.pathname;
  
  // ✅ Redirect based on country
  if (pathname === '/international' && country === 'US') {
    const url = request.nextUrl.clone();
    url.pathname = '/us';
    return NextResponse.redirect(url);
  }
  
  // ✅ Set locale based on country
  const response = NextResponse.next();
  response.cookies.set('preferred-country', country);
  
  return response;
}

export const config = {
  matcher: [
    '/international/:path*',
    '/regional/:path*',
  ],
  // ✅ Specify regions where middleware should run
  regions: ['us-east-1', 'eu-west-1'], // ✅ Optional: specify regions
};

Solution 5: Debugging Middleware Issues

// ✅ Debugging middleware with logging
// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  console.log('Middleware triggered for:', request.nextUrl.pathname);
  console.log('Method:', request.method);
  console.log('Headers:', Object.fromEntries(request.headers.entries()));
  
  // ✅ Check if middleware is running
  const response = NextResponse.next();
  response.headers.set('X-Middleware-Status', 'active');
  
  // ✅ Add timestamp
  response.headers.set('X-Processed-At', new Date().toISOString());
  
  return response;
}

// ✅ Broad matcher to ensure middleware runs
export const config = {
  matcher: [
    // ✅ Match all paths to debug
    '/:path*',
  ],
};

Solution 6: Multiple Middleware Files

// ✅ Main middleware file
// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  // ✅ Global middleware logic
  const response = NextResponse.next();
  response.headers.set('X-Global-Middleware', 'active');
  return response;
}

export const config = {
  matcher: [
    // ✅ Apply globally but exclude static assets
    {
      source: '/((?!_next/static|_next/image|favicon.ico).*)',
      missing: [
        { type: 'header', key: 'next-router-prefetch' },
      ],
    },
  ],
};
// ✅ API-specific middleware
// app/api/middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  // ✅ API-specific logic
  const authHeader = request.headers.get('authorization');
  
  if (!authHeader) {
    return new NextResponse('Unauthorized', { status: 401 });
  }
  
  return NextResponse.next();
}

export const config = {
  matcher: '/api/:function*',
};
Gautam Sharma

About Gautam Sharma

Full-stack developer and tech blogger sharing coding tutorials and best practices

Related Articles

next

Fix: useRouter only works in Client Components Error

Learn how to fix the 'useRouter only works in Client Components' error in Next.js applications. This comprehensive guide covers client components, server components, and proper routing implementation.

January 8, 2026
next

Fix: cookies() can only be used in Server Components error Next.js

Quick fix for 'cookies() can only be used in Server Components' error in Next.js. Learn how to properly use cookies in Server Components.

January 8, 2026
next

Fix: document is not defined in Next.js Error - Complete Client-Side Guide

Complete guide to fix 'document is not defined' error in Next.js applications. Learn how to handle browser APIs safely in server-side rendering environments.

January 8, 2026