next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Encoding issue with middleware rewrites and headers

Open franknoel opened this issue 1 month ago • 5 comments

Link to the code that reproduces this issue

https://github.com/franknoel/nextjs-bug-repro-middleware-encoding

To Reproduce

  1. Deploy https://github.com/franknoel/nextjs-bug-repro-middleware-encoding
  2. Add a header with a non-ASCII value, like Montréal. I'm using Cloudflare IP geolocation, which add cf-ipcity to the request.
  3. Load a page that uses the middleware

Exemple deployment: https://nextjs-bug-repro.pcobalt.com/

Current vs. Expected behavior

Errors from Vercel:

500: INTERNAL_SERVER_ERROR
Code: MIDDLEWARE_INVOCATION_FAILED
ID: cle1::w8596-1761928200824-a0b4989ee40e
Vercel Runtime Malformed Response Header Error: Header 'x-middleware-request-cf-ipcity: Montréal' contains non-ASCII characters.

I'd expect Next.js to support non-ASCII characters, like it did seamlessly before version 16.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:21 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 22.18.0
  npm: 10.9.3
  Yarn: N/A
  pnpm: 8.6.12
Relevant Packages:
  next: 16.0.2-canary.2 // Latest available version is detected (16.0.2-canary.2).
  eslint-config-next: N/A
  react: 19.2.0
  react-dom: 19.2.0
  typescript: 5.9.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Headers

Which stage(s) are affected? (Select all that apply)

Vercel (Deployed)

Additional context

This is working with Next.js v15 with next-intl v4.4.0 and prior versions. I first contacted Vercel support and they confirmed that it's a Next.js issue. They also said that I should open an issue on GitHub to report the problem.

As of today, the only workaround is to encode/decode each header manually. Although this works technically, it is not a real solution as any other header containing a non-ASCII character can break the middleware. It also adds a lot of unnecessary code into the proxy, which should be as light as possible.

franknoel avatar Oct 31 '25 16:10 franknoel

+1

Experiencing same issue with version v16. Was fine with v15.

kcsujeet avatar Nov 05 '25 15:11 kcsujeet

Hello! @franknoel fixed it , please let me know,

naaa760 avatar Nov 07 '25 04:11 naaa760

Got the same with Île-de-France :(

Vercel Runtime Malformed Response Header Error: Header 'x-middleware-request-cf-region: Île-de-France' contains non-ASCII characters.

Do we have an idea how to work around this issue in the meantime ? The work-around could be on the code side or on Vercel config side.

gadcam avatar Nov 10 '25 18:11 gadcam

Example work-around in proxy.ts (cf doc) in the meantime

import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';

// Needed because of https://github.com/vercel/next.js/issues/85631
function sanitizeHeaders(response: NextResponse): NextResponse {
  for (const [key, value] of response.headers.entries()) {
    if (!/^[\x00-\x7F]*$/.test(value)) {
      response.headers.delete(key);
    }
  }

  return response;
}

export function proxy(request: NextRequest) {
  const response = NextResponse.next();
  return sanitizeHeaders(response);
}

export const config = {
  matcher: '/*',
};

export default proxy;

gadcam avatar Nov 11 '25 14:11 gadcam

Just tried with the new v16.0.10 Next.js release and I can confirm that the issue is still there.

franknoel avatar Nov 12 '25 19:11 franknoel

The reproduction repository and example deployment are now on the latest canary release: 16.1.0-canary.29.

The proxy/middleware is still crashing.

franknoel avatar Dec 16 '25 17:12 franknoel