troubleshooting2025-07-25Β·15Β·1/348

Next.js Middleware Routing Error Solved - Real Troubleshooting Guide

How I fixed a Next.js middleware file naming issue that caused all routes to return 404 errors. Includes error logs, code analysis, and step-by-step solution.

Next.js Middleware Routing Error Solved

Introduction

Middleware is a core component in Next.js that handles routing logic. But when it doesn't work correctly, every page returns a 404 error.

This post documents a real Next.js middleware routing issue I encountered and how I solved it. If you're facing a similar problem, I hope this helps.

Environment

ItemValue
OSWindows 11
CPUAMD Ryzen 7 7800X3D
RAM32GB
RuntimeNode.js v20.5.0
FrameworkNext.js 14.2.5
LanguageTypeScript 5.3
i18nnext-intl 3.0

Problem

I was using next-intl for multi-language support and SEO. With localePrefix: 'as-needed', English pages were at root (/), other languages at prefixed paths (ko/, es/, ja/).

Suddenly, all pages started returning 404 errors.

Initial Symptoms

GET /calorie-calculator β†’ 404 Not Found
GET /blog β†’ 404 Not Found
GET /about β†’ 404 Not Found

Only the root path / worked. Every other path returned 404.

Root Cause Analysis

First Suspect: i18n Configuration

I checked next.config.js:

// next.config.js
const createNextIntlPlugin = require('next-intl/plugin');

const withNextIntl = createNextIntlPlugin('./i18n/request.ts');

module.exports = withNextIntl({
  reactStrictMode: true,
  images: {
    formats: ['image/avif', 'image/webp'],
  },
});

The configuration looked correct. But I needed to verify if createNextIntlPlugin was working properly.

Second Suspect: Middleware File Location

Next.js expects middleware.ts in the root directory. But I found the file was named proxy.ts:

// Wrong structure
/src
  /app
    ...
  /lib
    ...
  proxy.ts  ← This was acting as middleware

// Correct structure
/src
  /app
    ...
  /lib
    ...
middleware.ts  ← Must be in root

Next.js automatically detects middleware.ts during build. If it's named differently, Next.js won't recognize it as middleware.

Error Log

> Build error occurred
Error: Encountered an unknown middleware. Please ensure it exports a default function.
    at C:\Users\...\node_modules\next\dist\build\index.js:1847:23
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Solution Process

Step 1: Rename File

First, I renamed proxy.ts to middleware.ts:

# PowerShell command
Rename-Item -Path "proxy.ts" -NewName "middleware.ts"

After renaming, I ran the build again:

npm run build

But the error persisted. The file name alone wasn't enough.

Step 2: Analyze Middleware Code

I examined the middleware.ts code:

import createMiddleware from 'next-intl/middleware';

const locales = ['en', 'ko', 'es', 'ja'];
const defaultLocale = 'en';

export default createMiddleware({
  locales,
  defaultLocale,
  localePrefix: 'as-needed',
});

export const config = {
  matcher: ['/((?!api|_next|.*\\..*).*)'],
};

The code itself looked fine. But I suspected localePrefix: 'as-needed'.

Step 3: Analyze Routing Matching

localePrefix: 'as-needed' doesn't add prefixes for English:

  • /en/about β†’ redirects to /about
  • /ko/about β†’ stays at /ko/about

But there was a problem. The matcher pattern /((?!api|_next|.*\\..*).*) was catching all paths including /about.

Step 4: Understand Next.js Routing Priority

I researched Next.js routing priority:

  1. Static files in public/
  2. Build artifacts in _next/static/
  3. Pages in pages/ or app/
  4. Routing logic in middleware.ts

The issue was that middleware was intercepting all routes. Without NextResponse.rewrite(), Next.js couldn't find the path and returned 404.

Step 5: Add Rewrite Logic

The solution was to add NextResponse.rewrite() in middleware:

import { NextRequest, NextResponse } from 'next/server';
import createMiddleware from 'next-intl/middleware';

const locales = ['en', 'ko', 'es', 'ja'];
const defaultLocale = 'en';

const intlMiddleware = createMiddleware({
  locales,
  defaultLocale,
  localePrefix: 'as-needed',
});

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
  
  // Handle English locale
  if (pathname.startsWith('/en/')) {
    return NextResponse.redirect(
      new URL(pathname.replace('/en', ''), request.url),
      { status: 301 }
    );
  }
  
  // Handle regular paths (default English)
  if (pathname !== '/' && !locales.some(locale => pathname.startsWith(`/${locale}/`))) {
    return NextResponse.rewrite(
      new URL(`/${defaultLocale}${pathname}`, request.url),
      { headers: { 'x-next-intl-locale': defaultLocale } }
    );
  }
  
  return intlMiddleware(request);
}

export const config = {
  matcher: ['/((?!api|_next|.*\\..*).*)'],
};

Results

After the fix, I ran the build and tested:

$ npm run build
βœ“ Compiled successfully

Test Results

PathBeforeAfter
`/calorie-calculator`404200
`/blog`404200
`/about`404200
`/ko/about`404200
`/es/blog`404200

Lessons Learned

What I Learned

  1. File name matters: Next.js middleware must be named middleware.ts. Any other name won't work.

  2. Routing priority: Next.js has routing priorities. If middleware intercepts all routes without rewrite(), static files or page routing gets ignored.

  3. Importance of rewrite: NextResponse.rewrite() rewrites paths so Next.js can find the correct page.

  4. i18n interaction: localePrefix: 'as-needed' skips prefixes for English, but middleware needs logic to handle this.

Better Solutions

If I had done these, the problem could have been avoided:

  1. Use correct file name from start: Using middleware.ts from the beginning would prevent this issue.

  2. Check next-intl docs: Reading the middleware setup examples in next-intl documentation would have solved it faster.

  3. Unit testing: Unit tests for middleware routing would have caught the issue earlier.

Related Documentation

Conclusion

Next.js middleware is powerful, but a single misconfiguration can break the entire application. The problems covered in this post are common errors, and understanding the troubleshooting process helps deepen understanding of Next.js routing mechanics.

I hope this helps developers facing similar issues.


This post was written on 2025-07-25. Some content may differ if the technology stack versions have changed.

This blog does not accept any external sponsorships, affiliate marketing, or ad revenue. All analyses and recommendations are based purely on personal experience and official documentation.

For bug reports or technical questions, please submit via GitHub Issues.